---
title: Create namespace
description: Create a tenant isolation boundary that will contain collections.
doc_version: 0.1.0-preview
last_updated: 2026-09-14
---

# Create namespace

`POST /namespaces`

Create a tenant isolation boundary that will contain collections.

**Permission:** Cluster key.

[API key types and authentication](/engine/reference/authentication.md).

Send Idempotency-Key. Retry the same logical request with the same key and body. Idempotency records remain available for replay for 24 hours.

A new namespace returns 201. exist_ok returns 200 when the name already exists, without changing that namespace.

Usage counts describe resources and storage. Applications own tenant plan limits.

## Example request

```http
POST /namespaces HTTP/1.1
Host: engine.example.com
Authorization: Bearer <GRAPHON_ENGINE_API_KEY>
Content-Type: application/json
Idempotency-Key: 8f3c1e2a-4b5d-6e7f-8091-a2b3c4d5e6f7

{
  "name": "acme",
  "display_name": "Acme",
  "exist_ok": true
}
```

## Headers

### `Idempotency-Key`

**string · required**

Unique key for this logical operation. Reuse it only with the same request for retries. Retained for 86,400 seconds. A changed body returns idempotency_conflict.

## Request body

### `display_name`

**string · optional · nullable**

Human-readable label. This label does not change the resource name used in URLs.

### `exist_ok`

**boolean · optional**

Return the existing namespace with status 200 when this name exists. This does not update its label.

Default: `false`.

### `name`

**string · required**

URL name. Use 1–63 lowercase letters, digits, underscores, or hyphens. Start with a letter or digit. A name cannot match its resource ID format.

## Responses

### 201 · Namespace created

A new namespace with zero usage.

Content type: `application/json`.

#### Response headers

##### `x-request-id`

**string · required**

Request correlation ID. Retain it when investigating a failed or unexpected request.

##### `Location`

**string · required**

The path of the new resource, by ids.

```json
{
  "id": "ns_01K6Q6N7D8E9F0G1H2J3K4M5N6",
  "name": "acme",
  "display_name": "Acme",
  "usage": {
    "collections": 0,
    "files": 0,
    "source_bytes": "0",
    "index_bytes": "0"
  },
  "created_at": "2026-10-06T10:00:00Z",
  "updated_at": "2026-10-06T10:00:00Z"
}
```

#### Response fields

##### `created_at`

**string (date-time) · required**

Time the resource was created, as an ISO 8601 UTC timestamp.

##### `display_name`

**string · required · nullable**

Human-readable label. This label does not change the resource name used in URLs.

##### `id`

**string · required**

Immutable namespace ID with the ns_ prefix.

##### `name`

**string · required**

URL name. Use 1–63 lowercase letters, digits, underscores, or hyphens. Start with a letter or digit. A name cannot match its resource ID format.

##### `updated_at`

**string (date-time) · required**

Time the resource last changed, as an ISO 8601 UTC timestamp.

##### `usage`

**object · required**

Current resource counts and storage usage. These are measurements, not tenant plan quotas.

###### `usage.collections`

**integer · required**

Number of collections in this namespace.

###### `usage.files`

**integer · required**

Number of living files in this namespace.

###### `usage.index_bytes`

**string · required**

Bytes of derived index data, as a decimal string. May be "0" when the cluster does not report a measurement.

###### `usage.source_bytes`

**string · required**

Sum of declared source bytes for living files, as a decimal string. Files without a declared size count as zero.

### 200 · Namespace already exists

exist_ok returned the existing namespace without changing it.

Content type: `application/json`.

#### Response headers

##### `x-request-id`

**string · required**

Request correlation ID. Retain it when investigating a failed or unexpected request.

```json
{
  "id": "ns_01K6Q6N7D8E9F0G1H2J3K4M5N6",
  "name": "acme",
  "display_name": "Acme",
  "usage": {
    "collections": 1,
    "files": 1,
    "source_bytes": "77",
    "index_bytes": "0"
  },
  "created_at": "2026-10-06T10:00:00Z",
  "updated_at": "2026-10-06T10:00:00Z"
}
```

#### Response fields

##### `created_at`

**string (date-time) · required**

Time the resource was created, as an ISO 8601 UTC timestamp.

##### `display_name`

**string · required · nullable**

Human-readable label. This label does not change the resource name used in URLs.

##### `id`

**string · required**

Immutable namespace ID with the ns_ prefix.

##### `name`

**string · required**

URL name. Use 1–63 lowercase letters, digits, underscores, or hyphens. Start with a letter or digit. A name cannot match its resource ID format.

##### `updated_at`

**string (date-time) · required**

Time the resource last changed, as an ISO 8601 UTC timestamp.

##### `usage`

**object · required**

Current resource counts and storage usage. These are measurements, not tenant plan quotas.

###### `usage.collections`

**integer · required**

Number of collections in this namespace.

###### `usage.files`

**integer · required**

Number of living files in this namespace.

###### `usage.index_bytes`

**string · required**

Bytes of derived index data, as a decimal string. May be "0" when the cluster does not report a measurement.

###### `usage.source_bytes`

**string · required**

Sum of declared source bytes for living files, as a decimal string. Files without a declared size count as zero.

## Errors

[Error format and retry guidance](/engine/reference/errors.md).

### 400 · `invalid_request`

A field, path, parameter, or conditional request rule is invalid.

Correct the request. Unknown fields are rejected.

```json
{
  "error": {
    "code": "invalid_request",
    "message": "A field, path, parameter, or conditional request rule is invalid.",
    "request_id": "req_example",
    "retryable": false,
    "details": {}
  }
}
```

### 401 · `unauthenticated`

The API key is missing, invalid, or revoked.

Send an active key in Authorization: Bearer or X-API-Key.

```json
{
  "error": {
    "code": "unauthenticated",
    "message": "The API key is missing, invalid, or revoked.",
    "request_id": "req_example",
    "retryable": false,
    "details": {}
  }
}
```

### 403 · `forbidden`

The key can see the resource but lacks permission for this operation.

Use a key with the required action or scope kind.

```json
{
  "error": {
    "code": "forbidden",
    "message": "The key can see the resource but lacks permission for this operation.",
    "request_id": "req_example",
    "retryable": false,
    "details": {}
  }
}
```

### 409 · `already_exists`

The requested resource name already exists.

Use a new name. Namespace and collection creation also accept exist_ok to return an existing resource.

```json
{
  "error": {
    "code": "already_exists",
    "message": "The requested resource name already exists.",
    "request_id": "req_example",
    "retryable": false,
    "details": {}
  }
}
```

### 409 · `idempotency_conflict`

This idempotency key was already used with a different request body.

Reuse the original body for a retry, or choose a new key for a new operation.

```json
{
  "error": {
    "code": "idempotency_conflict",
    "message": "This idempotency key was already used with a different request body.",
    "request_id": "req_example",
    "retryable": false,
    "details": {}
  }
}
```

### 413 · `request_too_large`

The JSON request body exceeds 1,048,576 bytes.

Reduce the JSON body. Use upload or a URI source for larger file content.

```json
{
  "error": {
    "code": "request_too_large",
    "message": "The JSON request body exceeds 1,048,576 bytes.",
    "request_id": "req_example",
    "retryable": false,
    "details": {}
  }
}
```

### 503 · `temporarily_unavailable`

A dependency, cluster readiness condition, or capacity limit prevents this operation.

Inspect retryable and details. Retry only when permitted, preserving the idempotency key for the same write.

```json
{
  "error": {
    "code": "temporarily_unavailable",
    "message": "A dependency, cluster readiness condition, or capacity limit prevents this operation.",
    "request_id": "req_example",
    "retryable": true,
    "details": {}
  }
}
```

### 500 · `internal_error`

An unexpected server failure prevented this request from completing.

Retain x-request-id for investigation. Follow retryable before retrying a write.

```json
{
  "error": {
    "code": "internal_error",
    "message": "An unexpected server failure prevented this request from completing.",
    "request_id": "req_example",
    "retryable": false,
    "details": {}
  }
}
```

## Other request languages

### cURL

```bash
curl -sS -X POST "$GRAPHON_ENGINE_URL/namespaces" \
  -H "Authorization: Bearer $GRAPHON_ENGINE_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: 8f3c1e2a-4b5d-6e7f-8091-a2b3c4d5e6f7' \
  --data-raw '{
  "name": "acme",
  "display_name": "Acme",
  "exist_ok": true
}'
```

### Python

```python
import json
import os
import urllib.request

request = urllib.request.Request(
    os.environ["GRAPHON_ENGINE_URL"] + "/namespaces",
    data=json.dumps({"name": "acme", "display_name": "Acme", "exist_ok": True}).encode("utf-8"),
    headers={
        "Authorization": "Bearer " + os.environ["GRAPHON_ENGINE_API_KEY"],
        "Content-Type": "application/json",
        "Idempotency-Key": "8f3c1e2a-4b5d-6e7f-8091-a2b3c4d5e6f7",
    },
    method="POST",
)
with urllib.request.urlopen(request) as response:
    print(response.read().decode())
```

### JavaScript

```javascript
const response = await fetch(process.env.GRAPHON_ENGINE_URL + "/namespaces", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.GRAPHON_ENGINE_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "8f3c1e2a-4b5d-6e7f-8091-a2b3c4d5e6f7",
  },
  body: JSON.stringify({"name":"acme","display_name":"Acme","exist_ok":true}),
});
console.log(response.status, await response.text());
```

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
