API Documentation

Everything you and your agents need to integrate with PlanetGraph.

Quick Start

Start with these prompts in your preferred coding agent, then iterate with follow-up questions.

Sign up to get your API key

Interactive

Explore the live OpenAPI reference, authorize with an API key, and try requests directly against the API.

Open interactive API docs open_in_new

Authentication

Use X-API-Key for API keys. Authorization: Bearer ... is only for Firebase user tokens.

curl -H "X-API-Key: YOUR_API_KEY" \
  https://api.planetgraph.ai/api/v1/nodes

Operating Principles

PlanetGraph is a data layer for storing and sharing knowledge graphs.

The core entities in a knowledge graph are Nodes, Edges, and Properties. Edges connect Nodes to other Nodes. Properties can be attached to both Nodes and Edges.

Nodes and Edges are public by default. Properties are private by default and subject to access policies.

Property Sharing

If a Property owner wants to share a Property, they create an access policy that defines the cost in tokens to access that Property (which can be 0, meaning free to access).

A simple example:

  • User A creates a Node representing Acme Corp.
  • User B knows the URL of Acme Corp and attaches it as a Property to the Acme Corp Node.
  • User B sets a price of 10 tokens to access that Property.
  • User C searches for and finds Acme Corp and pays 10 tokens to access the URL Property.
  • User B receives 10 tokens.

Searching

PlanetGraph data can be queried in multiple ways, including:

  • as a graph, using Cypher
  • via property search (using relational queries)
  • through semantic search

Searching is controlled by Search Rules, which define whether and how a given Property can be searched. Only a Property owner can define the Search Rule for their Property.

Making a Property searchable does not reveal its value.

Account & API Keys

Inspect your account identity and manage API keys for integrations.

GET/api/v1/api-keys

List Api Keys

POST/api/v1/api-keys

Create Api Key

DELETE/api/v1/api-keys/{key_id}

Revoke Api Key

POST/api/v1/auth/mfa/recovery-code

Use Recovery Code

GET/api/v1/me

Get Me

GET/api/v1/me/security

Get Security Status

GET/api/v1/me/security/recovery-codes

Get Recovery Code Status

POST/api/v1/me/security/recovery-codes

Regenerate Recovery Codes

Nodes

Create, read, update, and delete graph nodes.

GET/api/v1/nodes

List Nodes

POST/api/v1/nodes

Create Node

GET/api/v1/nodes/{node_id}

Get Node

PATCH/api/v1/nodes/{node_id}

Update Node

DELETE/api/v1/nodes/{node_id}

Delete Node

POST/api/v1/nodes/neighborhood

Load Neighborhood

GET/api/v1/nodes/types

List Node Types

Edges

Create and manage relationships between nodes.

GET/api/v1/edges

List Edges

POST/api/v1/edges

Create Edge

GET/api/v1/edges/{edge_id}

Get Edge

PATCH/api/v1/edges/{edge_id}

Update Edge

DELETE/api/v1/edges/{edge_id}

Delete Edge

GET/api/v1/edges/by-node/{node_id}

List Edges For Node. List all edges (incoming + outgoing) for a node.

GET/api/v1/edges/types

List Edge Types

Properties

Manage properties on nodes and edges with granular access controls.

POST/api/v1/admin/rotate-keys/{account_id}

Rotate Keys

GET/api/v1/edges/{edge_id}/properties

List Edge Properties. List Property metadata for a visible Edge. Hidden Edges behave as not found for non-owners. Property values are returned only when the caller owns the Property or has value access through a grant or free policy.

POST/api/v1/edges/{edge_id}/properties

Create or Replace Edge Property. Create a Property owned by the caller on a visible Edge, or replace the value when the caller already owns the Property with that name. Property names are unique per Edge; a collision with another owner's Property returns 409. API keys and bearer tokens are both accepted. The caller does not need to own the Edge, but hidden Edges behave as not found for non-owners.

GET/api/v1/nodes/{node_id}/properties

List Node Properties. List Property metadata for a visible Node. Hidden Nodes behave as not found for non-owners. Property values are returned only when the caller owns the Property or has value access through a grant or free policy.

POST/api/v1/nodes/{node_id}/properties

Create or Replace Node Property. Create a Property owned by the caller on a visible Node, or replace the value when the caller already owns the Property with that name. Property names are unique per Node; a collision with another owner's Property returns 409. API keys and bearer tokens are both accepted. The caller does not need to own the Node, but hidden Nodes behave as not found for non-owners.

PUT/api/v1/properties/{property_id}

Update Property. Update a Property value or searchability metadata. Only the Property owner may update it.

DELETE/api/v1/properties/{property_id}

Delete Property. Delete a Property. Only the Property owner may delete it.

POST/api/v1/properties/batch-get

Batch Get Node or Edge Properties. Read policy-checked Properties for 1-100 distinct Node or Edge IDs in one call, in request order. API keys and bearer tokens are both accepted; MCP is not required. Each request selects one resource_type (node or edge), optionally 1-25 distinct property_names, and property_limit (1-25, default 25) per resource. Accessible values are returned; locked Properties retain metadata and price without revealing values or purchasing access. Empty resources return an empty properties list. properties_truncated indicates additional matching Properties; narrow property_names to read specific fields (there is no continuation cursor). This returns Properties grouped by supplied IDs, not full Node/Edge records. Any missing, deleted or hidden resource fails the entire batch with a generic 404. Selected encrypted Property payloads exceeding 4,000,000 bytes return 413; request fewer resources or names.

Bulk Imports

Asynchronously create or upsert Nodes, Edges, and Properties in bulk.

Import Format

The current import format is version 1. It supports upsert or create_only mode and uses stable external_id values.

Every import also needs an idempotency_key. This is a key you generate and is unique within your account. If you repeat the same logical import with the same key, PlanetGraph returns the existing job instead of creating a duplicate.

Inline JSON Imports

For small imports (up to 1 MiB, or 1,048,576 bytes, by default), send the complete import document as JSON to POST /api/v1/imports.

{
  "version": 1,
  "mode": "upsert",
  "idempotency_key": "crm-export-2026-07-31",
  "nodes": [
    {
      "external_id": "person:123",
      "type": "Person",
      "visibility": "owner_only"
    }
  ],
  "edges": [],
  "properties": [
    {
      "external_id": "person:123:name",
      "resource_external_id": "person:123",
      "resource_type": "node",
      "resource_entity_type": "Person",
      "name": "name",
      "type": "string",
      "value": "Ada"
    }
  ]
}

The response is 202 Accepted and includes the import job ID.

JSONL File Imports

For larger imports (up to 50 MiB, or 52,428,800 bytes, by default), use the following signed JSONL upload flow.

  1. Calculate the completed JSONL file's exact byte count.
  2. Reserve an upload by sending the following JSON to POST /api/v1/imports/uploads:
    {"expected_bytes": 12345}
  3. The response includes an upload_url, an upload_id, and required_headers.
  4. PUT the JSONL file to upload_url. Include every returned required_headers value exactly, including Content-Type and Content-Length. Do NOT send your PlanetGraph API key to the storage URL.
  5. Finalize the uploaded file by sending the job metadata below to POST /api/v1/imports/uploads/{upload_id}/finalize.

Example JSONL File

Each nonblank line is a complete JSON object. The kind field identifies the item type:

{"kind":"node","external_id":"person:123","type":"Person","visibility":"owner_only"}
{"kind":"node","external_id":"company:7","type":"Company","visibility":"public"}
{"kind":"edge","external_id":"works:123:7","type":"WORKS_AT","source_external_id":"person:123","source_type":"Person","target_external_id":"company:7","target_type":"Company","visibility":"owner_only"}
{"kind":"property","external_id":"person:123:name","resource_external_id":"person:123","resource_type":"node","resource_entity_type":"Person","name":"name","type":"string","value":"Ada"}

Finalization Metadata

This finalization request describes the import job. The imported items remain in the uploaded JSONL file and are not repeated here.

{
  "version": 1,
  "mode": "upsert",
  "idempotency_key": "crm-export-2026-07-31"
}

The finalization response is 202 Accepted and includes the import job ID.

Check Progress and Results

Use the import job ID returned by either submission method:

GET /api/v1/imports/{import_id}
GET /api/v1/imports/{import_id}/results?limit=1000&offset=0
GET /api/v1/imports/{import_id}/errors?limit=1000&offset=0

Poll the status endpoint until the job reaches completed, completed_with_errors, failed, or cancelled. Page through results or errors by increasing offset until the response contains fewer records than limit.

Imports preserve normal ownership, billing, encryption, access, search, projection, and embedding behavior.

Endpoint Reference

GET/api/v1/imports

List Imports

POST/api/v1/imports

Create Import. Submit a complete JSON import manifest in the request body, limited to 1 MiB (1,048,576 bytes). Larger imports should use the signed JSONL uploads route, which accepts files up to 128 MiB in production. default_visibility applies only to new nodes and edges that omit visibility; existing records preserve visibility unless explicitly changed.

GET/api/v1/imports/{import_id}

Get Import

POST/api/v1/imports/{import_id}/cancel

Cancel Import

GET/api/v1/imports/{import_id}/errors

Get Import Errors

GET/api/v1/imports/{import_id}/results

Get Import Results

POST/api/v1/imports/{import_id}/retry

Retry Import

POST/api/v1/imports/uploads

Create Import Upload. Reserve a signed JSONL file upload. Production accepts files up to 128 MiB (134,217,728 bytes). Use this route for imports exceeding the inline 1 MiB request limit; the file is uploaded directly to cloud storage, not in this API request.

POST/api/v1/imports/uploads/{upload_id}/finalize

Finalize Import Upload

Queries

Execute Cypher queries and access query history.

POST/api/v1/queries/answer

Answer Query

POST/api/v1/queries/build

Build Query

GET/api/v1/queries/build/{build_id}

Retrieve Build

POST/api/v1/queries/build/stream

Build Query Stream

GET/api/v1/queries/builds

Build History

GET/api/v1/queries/history

Query History

GET/api/v1/queries/planner-prompt

Planner Prompt

GET/api/v1/queries/runs/{run_id}

Retrieve Run

POST/api/v1/queries/runs/{run_id}/api-guide

Generate Api Guide

POST/api/v1/query

Run Query

Billing

Manage your token balance and view transaction history.

GET/api/v1/account/balance

Account Balance

POST/api/v1/account/purchase

Purchase Tokens

GET/api/v1/account/transactions

Account Transactions

POST/api/v1/admin/pricing

Create Pricing

GET/api/v1/pricing

Get Pricing

Access Control

Define and manage access policies for your data.

GET/api/v1/access-policies

List Access Policies. List Access Policies owned by the caller's Account. API keys and Firebase bearer tokens are both accepted.

POST/api/v1/access-policies

Create Access Policy. Create an Access Policy owned by the caller's Account. API keys and Firebase bearer tokens are both accepted.

PUT/api/v1/access-policies/{policy_id}

Update Access Policy. Update an Access Policy owned by the caller's Account. API keys and Firebase bearer tokens are both accepted.

DELETE/api/v1/access-policies/{policy_id}

Delete Access Policy. Delete an unreferenced Access Policy owned by the caller's Account. API keys and Firebase bearer tokens are both accepted.

PATCH/api/v1/feedback/{feedback_id}

Update Feedback

DELETE/api/v1/feedback/{feedback_id}

Delete Feedback

PATCH/api/v1/properties/{property_id}/access-policy

Assign Access Policy

GET/api/v1/properties/{property_id}/feedback

List Feedback

POST/api/v1/properties/{property_id}/feedback

Create Feedback

POST/api/v1/properties/{property_id}/purchase

Purchase Property Access

POST/api/v1/properties/purchase/bulk

Purchase Bulk Property Access

POST/api/v1/properties/purchase/quote

Quote Bulk Property Access

GET/api/v1/property-access-rules

List Property Access Rules. List type-level Property Access rules owned by the caller's Account.

PUT/api/v1/property-access-rules

Upsert Property Access Rule. Create or update a type-level Property Access rule owned by the caller's Account. The Access Policy must belong to the same Account. API keys and Firebase bearer tokens are both accepted.

DELETE/api/v1/property-access-rules/{rule_id}

Delete Property Access Rule. Delete a type-level Property Access rule owned by the caller's Account. API keys and Firebase bearer tokens are both accepted.

GET/api/v1/searchability/property-search-rules

List Property Search Rules. List the caller's Account-owned Property Search rules. API keys and Firebase bearer tokens are both accepted.

PUT/api/v1/searchability/property-search-rules

Upsert Property Search Rule. Create or update a Property Search rule that applies only to the caller's Account-owned Properties. Explicit Property search settings override rule defaults. Requires a recent Firebase bearer-token sign-in; API keys are not accepted.

DELETE/api/v1/searchability/property-search-rules/{rule_id}

Delete Property Search Rule. Delete a Property Search rule owned by the caller's Account. Requires a recent Firebase bearer-token sign-in; API keys are not accepted.

Audit Logs

Review account-scoped activity for traceability and compliance workflows.

GET/api/v1/audit-logs

List Audit Logs

PlanetGraph Login+

Login your users through PlanetGraph and gain additional insights

Read the PlanetGraph Login+ guide arrow_forward