POST /bootstrap
curl --request POST \
--url https://api-zangtable.com/bootstrap \
--header 'Authorization: <authorization>'import requests
url = "https://api-zangtable.com/bootstrap"
headers = {"Authorization": "<authorization>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: '<authorization>'}};
fetch('https://api-zangtable.com/bootstrap', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-zangtable.com/bootstrap",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-zangtable.com/bootstrap"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-zangtable.com/bootstrap")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-zangtable.com/bootstrap")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body{
"ok": true,
"data": {},
"error": {},
"request_id": "<string>"
}Projects
POST /bootstrap
Creates a project with tables, indexes, seed records, and optional Project API Tokens in one request.
POST
https://api-zangtable.com
/
bootstrap
POST /bootstrap
curl --request POST \
--url https://api-zangtable.com/bootstrap \
--header 'Authorization: <authorization>'import requests
url = "https://api-zangtable.com/bootstrap"
headers = {"Authorization": "<authorization>"}
response = requests.post(url, headers=headers)
print(response.text)const options = {method: 'POST', headers: {Authorization: '<authorization>'}};
fetch('https://api-zangtable.com/bootstrap', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api-zangtable.com/bootstrap",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api-zangtable.com/bootstrap"
req, _ := http.NewRequest("POST", url, nil)
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api-zangtable.com/bootstrap")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api-zangtable.com/bootstrap")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body{
"ok": true,
"data": {},
"error": {},
"request_id": "<string>"
}Creates a project and loads its starting schema/data in one request.
Agent automation may use a short-lived
Full request:
Error or alternate response:
agp_ provisioning token for this endpoint.
An agm_ master key is not accepted directly. See Agent Tokens
for the minting flow and required account-user ownership.
Use this when your backend wants to spin up a new ZangTable project from a template instead of making separate calls for project creation, table creation, indexes, seed records, and token creation.
Endpoint details
string
required
Bearer
pat_... (existing human-issued Project API Token) or agp_... (short-lived Agent provisioning token). The project is created in the credential’s account. Keep credentials server-side.boolean
required
true for a successful response and false for an error response.object | null
Endpoint-specific response data when
ok is true; null on errors.object | null
Error code and message when
ok is false; null on success.string
required
Request identifier you can use when troubleshooting a specific API call.
Authentication
Project API Token.Parameters
Body fields:project_slug(string, required): New project slug. Use lowercase letters, numbers, hyphens, or underscores.project_name(string, required): Human-readable project name.initial_project_user(object, required): Initial project user withusernameandpassword.tables(array, optional): Tables to create. Each table may includetable_name,display_name,columns,seed, and table-levelindexes.indexes(array, optional): Additional project-level indexes. Each index includestable_name,columns, optionalindex_name, and optionalunique.project_api_tokens(array, optional): Project API Tokens to mint for the new project. Each item includesaccount_user_id, optionaltoken_name, and optionalproject_username.
column_nameorname(string, required)column_typeortype(string, optional):INTEGER,REAL,TEXT,BLOB, orANY. Defaults toTEXT.is_primaryorprimary(boolean, optional)is_uniqueorunique(boolean, optional)is_nullableornullable(boolean, optional)default_valueordefault(scalar or null, optional)
Notes
- The request creates one project on the same account as the Project API Token you use.
project_slugmust be unique and cannot already have project storage.- Account plan project limits still apply.
- Seed values must be scalar values or
null. - Seed records may only reference columns declared for their table.
project_api_tokens.account_user_idmust be an active user on the same ZangTable account.- The bootstrap endpoint currently creates tokens only for the
initial_project_user. - Raw Project API Tokens are only returned in the creation response. Store them securely.
Request examples
Basic request:curl -X POST "$BASE_URL/bootstrap" \
-H 'Authorization: Bearer pat_PROJECT_TOKEN' \
-H 'Content-Type: application/json' \
--data '{"project_slug":"customer_portal","project_name":"Customer Portal","initial_project_user":{"username":"server","password":"replace-with-a-long-password"}}'
curl -X POST "$BASE_URL/bootstrap" \
-H 'Authorization: Bearer pat_PROJECT_TOKEN' \
-H 'Content-Type: application/json' \
-H 'X-Operation-Key: bootstrap-customer-portal' \
-H 'X-Operation-Run-Id: oprun_client_20260617_001' \
--data '{
"project_slug": "customer_portal",
"project_name": "Customer Portal",
"initial_project_user": {
"username": "server",
"password": "replace-with-a-long-password"
},
"tables": [
{
"table_name": "customers",
"display_name": "Customers",
"columns": [
{"column_name": "id", "column_type": "INTEGER", "is_primary": true, "is_nullable": false},
{"column_name": "email", "column_type": "TEXT", "is_nullable": false, "is_unique": true},
{"column_name": "name", "column_type": "TEXT"},
{"column_name": "created_at", "column_type": "TEXT"}
],
"seed": [
{"email": "hello@example.com", "name": "Example Customer", "created_at": "2026-06-17T04:00:00Z"}
],
"indexes": [
{"columns": ["created_at"]}
]
}
],
"project_api_tokens": [
{
"account_user_id": 123,
"token_name": "customer-portal-server"
}
]
}'
Response examples
Success:{
"ok": true,
"data": {
"project": {
"id": 1,
"project_slug": "customer_portal",
"project_name": "Customer Portal",
"created_at": "2026-06-17T04:00:00Z",
"updated_at": "2026-06-17T04:00:00Z"
},
"registry": {
"id": 44,
"account_id": 12,
"project_slug": "customer_portal",
"project_name": "Customer Portal",
"status": "active",
"created_at": "2026-06-17T04:00:00Z",
"updated_at": "2026-06-17T04:00:00Z"
},
"initial_project_user": {
"id": 1,
"username": "server",
"is_owner": 1,
"is_active": 1,
"created_at": "2026-06-17T04:00:00Z",
"updated_at": "2026-06-17T04:00:00Z",
"last_login_at": null
},
"created": {
"tables": 1,
"seed_records": 1,
"indexes": 1,
"project_api_tokens": 1
},
"project_api_tokens": [
{
"token": "pat_NEW_PROJECT_TOKEN",
"token_id": 1,
"token_type": "project_api_token",
"token_name": "customer-portal-server",
"account_user_id": 123,
"project_user_id": 1,
"project_username": "server",
"expires_at": null
}
]
},
"error": null,
"request_id": "req_20260617T040000_123456Z_abc123def456",
"operation_key": "bootstrap-customer-portal",
"operation_run_id": "oprun_client_20260617_001",
"operation_grouping_status": "accepted_provided_run",
"meta": {
"generated_at": "2026-06-17T04:00:01Z"
}
}
{
"ok": false,
"data": null,
"error": {
"code": "project_exists",
"message": "A project with that slug already exists."
},
"request_id": "req_20260617T040000_123456Z_abc123def456",
"meta": {
"generated_at": "2026-06-17T04:00:01Z"
}
}