---
title: "Create New Graph Database"
method: POST
path: "/v1/graphs"
tags: ["Graphs"]
---

# Create New Graph Database

`POST /v1/graphs`

## Request

- Base URL: `https://api.robosystems.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.robosystems.ai/v1/graphs`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Creates a graph asynchronously. Returns an `OperationEnvelope` with `operation_id` for SSE progress at `/v1/operations/{operation_id}/stream`. Entity graphs require `initial_entity`. Supports `Idempotency-Key` header.

## Headers

- `Idempotency-Key` string, nullable

## Request body

- CreateGraphRequest: Request model for creating a new graph. Use this to create either: - **Entity graphs**: Standard graphs with entity schema. Requires `initial_entity`. - **Custom graphs**: Generic graphs with a fully custom schema. Requires `custom_schema`; `initial_entity` is not used.
  - `metadata` GraphMetadata, required: Metadata for graph creation.
    - `graph_name` string, required: Display name for the graph
    - `description` string, nullable: Optional description
    - `schema_extensions` string[]: Schema extensions to enable
    - `tags` string[]: Tags for organizing graphs
  - `instance_tier` string: Instance tier: ladybug-standard, ladybug-large, ladybug-xlarge
  - `custom_schema` CustomSchemaDefinition: Custom node and relationship types for a generic graph. For graphs that don't fit the entity-based schema — inventory, org charts, project management. `extends` names a base schema to build on, or is omitted for a bare database.
    - `name` string, required: Schema name
    - `version` string: Schema version
    - `description` string, nullable: Schema description
    - `extends` string, nullable: Base schema to extend (e.g., 'base' for common utilities)
    - `nodes` object[]: List of node definitions with properties
    - `relationships` object[]: List of relationship definitions
    - `metadata` object: Additional schema metadata
  - `initial_entity` InitialEntityData: Initial entity data for entity-focused graph creation. When creating an entity graph with an initial entity node, this model defines the entity's identifying information and metadata.
    - `name` string, required: Entity name
    - `uri` string, required: Entity website or URI
    - `ticker` string, nullable: Entity symbol/ticker (e.g., 'HARB', 'NVDA'). Auto-generated from name if not provided.
    - `cik` string, nullable: CIK number for SEC filings
    - `sic` string, nullable: SIC code
    - `sic_description` string, nullable: SIC description
    - `category` string, nullable: Business category
    - `state_of_incorporation` string, nullable: State of incorporation
    - `fiscal_year_end` string, nullable: Fiscal year end (MMDD)
    - `ein` string, nullable: Employer Identification Number
    - `entity_type` string, nullable: Entity legal form (e.g. 'corporation', 'llc' / 'limited_liability_company', 'partnership', 'sole_proprietorship', 'non_profit'). Drives the graph's default Reporting Style at creation — partnership and llc get dedicated equity-form Styles; everything else defaults to corporate. Blank falls back to corporate.
    - `reporting_style_id` string, nullable: Optional explicit Reporting Style Structure id to pin on the entity, overriding the entity_type-derived default. Leave blank to derive from entity_type. Change later via the change-reporting-style operation.
  - `create_entity` boolean: Whether to create the entity node and upload initial data. Only applies when initial_entity is provided. Set to False to create graph without populating entity data (useful for file-based ingestion workflows).
  - `tags` string[]: Optional tags for organization

## Response `202`

Successful Response

- OperationEnvelope: Uniform response shape for every operation endpoint. Every dispatch carries an `op_<ULID>` operation_id, which is the bridge to the monitoring surface: pass it to `GET /v1/operations/{operation_id}/stream` (see `routers/operations.py`) to subscribe to SSE progress events. Sync commands complete in the envelope itself (`status: "completed"`, HTTP 200); async commands (`status: "pending"`, HTTP 202) hand off to a background worker and stream their tail through that SSE endpoint. Failed dispatches still mint an `operation_id` so the audit log and any partial SSE events stay correlatable. `TResult` parameterizes `result` so per-op response shapes surface in OpenAPI. Operations that pin `OperationSpec.result_type` get `OperationEnvelope[YourEnvelope]` as their response model; the rest keep the default `Any` shape (`result: any | null` on the wire).
  - `operation` string, required: Kebab-case operation name
  - `operationId` string, required: op_-prefixed ULID for audit and SSE correlation
  - `status` 'completed' | 'pending' | 'failed', required: Operation lifecycle state
  - `result` unknown
  - `at` string, required: ISO-8601 UTC timestamp
  - `createdBy` string, nullable: User ID that initiated the operation
  - `idempotentReplay` boolean: True when this envelope came from the idempotency cache — the underlying command did not execute again. False on fresh executions.

## Other responses

- `400`: Invalid request
- `401`: Authentication required
- `402`: Payment required — add a payment method or check org graph limit
- `403`: Access denied
- `404`: Resource not found
- `409`: Idempotency-Key conflict — key reused with different body
- `422`: Validation error
- `429`: Rate limit exceeded
- `500`: Internal server error

---

[API](https://skmtc.dev/robosystems/apis/robosystems-api.md) · [All operations](https://skmtc.dev/robosystems/apis/robosystems-api/llms.txt) · [OpenAPI document](https://skmtc.dev/robosystems/apis/robosystems-api/revisions/e661e2d5ca6a?raw)
