POST /v1/organizations
Create a child organization — one isolated tenant per customer.
POST
/v1/organizationsPhase 1stableidempotent
- Auth
- Bearer
- Scope
- org:admin
Create a child organization under your (parent) org — one per end-customer. The child is an isolation boundary: its projects, credits, audit log, and keys are invisible to its siblings. The call is synchronous and idempotent via the Idempotency-Key header.
The new org starts in status: "active" with an empty, isolated credit wallet. Operate inside it with your parent key plus the X-Layers-Organization header. See the walkthrough.
The hierarchy is one level deep. You can only create children under a top-level (parent) org — a child org cannot itself create children. Attempting it returns 422 VALIDATION.
Headers
Idempotency-Keystring (UUID)optionalOptional but strongly recommended. Same key + same body replays the cached response (`409 IDEMPOTENCY_CONFLICT` on body mismatch). Without it, a retry after a connection error creates a duplicate org. See [Idempotency](/docs/api/operational/idempotency).
Body
namestringrequiredDisplay name for the customer org. 1–128 chars.metadataobject<string,string>optionalOpaque key/value pairs you control (your customer id, plan tier, etc.). String values only; keys ≤ 40 chars, values ≤ 500 chars, ≤ 50 keys (16 KB hard cap as a backstop). Round-tripped unchanged; Layers never reads or indexes it.billingEmailstringoptionalOptional contact email for this customer org. Informational.
Example request
curl https://api.layers.com/v1/organizations \
-H "Authorization: Bearer $PARENT_KEY" \
-H "Idempotency-Key: 4c1a2e92-7b18-4c4b-9b2a-d7a3f8b1c210" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Coffee",
"metadata": { "externalId": "cust_12345", "plan": "growth" },
"billingEmail": "ops@acme.example"
}'const org = await fetch("https://api.layers.com/v1/organizations", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.PARENT_KEY}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "Acme Coffee",
metadata: { externalId: "cust_12345", plan: "growth" },
billingEmail: "ops@acme.example",
}),
}).then((r) => r.json());import os, uuid, requests
org = requests.post(
"https://api.layers.com/v1/organizations",
headers={
"Authorization": f"Bearer {os.environ['PARENT_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
"Content-Type": "application/json",
},
json={
"name": "Acme Coffee",
"metadata": {"externalId": "cust_12345", "plan": "growth"},
"billingEmail": "ops@acme.example",
},
).json()Response
201Created
{
"id": "org_d4e5f6a7-8b9c-4d0e-9f2a-3b4c5d6e7f80",
"parentOrganizationId": "org_2481fa5c-a404-44ed-a561-565392499abc",
"name": "Acme Coffee",
"status": "active",
"metadata": { "externalId": "cust_12345", "plan": "growth" },
"billingEmail": "ops@acme.example",
"archivedAt": null,
"createdAt": "2026-06-01T14:30:00.000000+00:00",
"updatedAt": "2026-06-01T14:30:00.000000+00:00"
}Field notes
idis the child org'sorg_-prefixed id. Pass it as the:orgIdpath param on the other org endpoints, or as theX-Layers-Organizationheader to act inside it.parentOrganizationIdis your org — always set on a child.statusis alwaysactiveon create. Move it with suspend / resume / archive.archivedAtis alwaysnullon create; it carries a timestamp only once the org is archived.metadataisnullwhen you don't send it.
Errors
| Status | Code | When |
|---|---|---|
| 422 | VALIDATION | name empty or > 128 chars; metadata violates the string/≤40-key/≤500-value/≤50-keys bounds (or the 16 KB backstop); or the calling org is itself a child (hierarchy is one level deep). |
| 401 | UNAUTHENTICATED | Missing or invalid key. |
| 403 | FORBIDDEN_SCOPE | Key lacks org:admin. The control plane is deny-by-default — the scope must be held explicitly. |
| 409 | IDEMPOTENCY_CONFLICT | Same Idempotency-Key replayed with a different body. |
| 429 | RATE_LIMITED | Write budget exhausted. |
See also
- Organizations concept — the parent/child model and lifecycle.
GET /v1/organizations— list your children.- Manage customers with sub-organizations — the end-to-end flow.