Skip to content

Management API ​

Use the Management API to manage your Inodra account from code. It is for AI agents, scripts and CI jobs.

With it you can:

  • List, create and disable API keys
  • List and create projects
  • Read the organization, plan and prepaid balance
  • Pay a monthly plan with USDC on Sui

For the dashboard, see API Keys and Sign in with Sui.

Authentication ​

Send an API key in the x-api-key header. The key must have the manage scope.

bash
curl https://mainnet-api.inodra.com/v1/account \
  -H "x-api-key: indr_pat_..."

You can use either of these keys:

  • The key from POST /v1/wallet/register. It has data, streams and manage.
  • A key that you create in the dashboard with the Manage scope.

Base URLs:

NetworkBase URL
Mainnethttps://mainnet-api.inodra.com
Testnethttps://testnet-api.inodra.com

Scopes ​

ScopeGrants access to
dataChain reads (gRPC, GraphQL, JSON-RPC)
streamsConnections to Warp streams
manageWebhooks, Warp streams, usage, API keys, projects and account data

See API Key Scopes for the full model.

Important: A manage key is an admin credential for the whole organization. It can create, rotate and revoke every key in it, including keys it did not create. Keep it on the server and off agent and CI hosts. For a workload, create a separate key with only the data scope.

API Keys ​

List Keys ​

bash
curl https://mainnet-api.inodra.com/v1/keys \
  -H "x-api-key: indr_pat_..."

Response 200:

json
{
  "data": [
    {
      "id": "<key id>",
      "name": "indexer-worker",
      "start": "indr_pat_ab",
      "prefix": "indr_pat_",
      "projectId": "...",
      "scopes": ["data"],
      "enabled": true,
      "expiresAt": "2026-10-24T12:00:00.000Z",
      "createdAt": "2026-09-24T12:00:00.000Z"
    }
  ]
}
  • The list shows every key in the organization.
  • The response never contains the secret. start shows the first characters only.

Create a Key ​

bash
curl -X POST https://mainnet-api.inodra.com/v1/keys \
  -H "x-api-key: indr_pat_..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "indexer-worker", "projectId": "<project id>", "scopes": ["data"], "expiresInDays": 30 }'

Request body:

FieldRequiredDescription
nameYesA name for the key
projectIdYesA project in your organization
scopesNoDefault ["data"]. Only scopes that the calling key has
expiresInDaysNo1 to 365. Default 30

Response 201:

json
{
  "data": {
    "id": "<key id>",
    "apiKey": "indr_pat_...",
    "name": "indexer-worker",
    "projectId": "...",
    "scopes": ["data"],
    "expiresAt": "2026-10-24T12:00:00.000Z"
  }
}

Rules:

  • apiKey is shown once. Store it at once. You cannot get it again.
  • A new key can only get scopes that the calling key has. If not, Inodra answers 403 with SCOPE_ESCALATION.
  • The project must belong to your organization. If not, Inodra answers 404 with PROJECT_NOT_FOUND.

Disable a Key ​

bash
curl -X DELETE https://mainnet-api.inodra.com/v1/keys/<key id> \
  -H "x-api-key: indr_pat_..."

Response 200:

json
{
  "data": { "id": "<key id>", "enabled": false }
}
  • The key stops working at once.
  • You can disable the key that you use for the call. Later calls with that key fail.

Projects ​

List Projects ​

bash
curl https://mainnet-api.inodra.com/v1/projects \
  -H "x-api-key: indr_pat_..."

Response 200:

json
{
  "data": [
    {
      "id": "...",
      "name": "Main",
      "slug": "main",
      "network": "mainnet",
      "createdAt": "2026-09-24T12:00:00.000Z"
    }
  ]
}

Create a Project ​

bash
curl -X POST https://mainnet-api.inodra.com/v1/projects \
  -H "x-api-key: indr_pat_..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "Staging", "network": "testnet" }'
  • network is mainnet or testnet.
  • On success, Inodra answers 201 with the new project.
  • If a project with the same slug exists, Inodra answers 409 with PROJECT_SLUG_TAKEN.
  • Your plan sets how many projects you can have. At the limit, Inodra answers 403 with PROJECT_LIMIT_REACHED. A wallet organization has one mainnet project.

Account ​

bash
curl https://mainnet-api.inodra.com/v1/account \
  -H "x-api-key: indr_pat_..."

Response 200:

json
{
  "data": {
    "organization": { "id": "...", "name": "...", "walletAddress": "0x..." },
    "tier": "wallet",
    "subscription": { "plan": "...", "status": "...", "periodEnd": "..." },
    "key": {
      "id": "<key id>",
      "name": "...",
      "scopes": ["data", "streams", "manage"],
      "projectId": "...",
      "expiresAt": "..."
    },
    "balance": { "credits": "500000", "usd": "5.000000" }
  }
}
  • key describes the key that made the call.
  • balance is present only for wallet organizations. It is the prepaid x402 balance. Both fields are strings.
  • Management calls are not metered. They work at zero balance.

Billing ​

Pay a monthly plan with USDC on Sui. For the full flow, see Pay for a plan with USDC on Sui.

List Plans ​

Returns the networks, the spender address, the treasury address, the package ID, the coins and the plan prices.

bash
curl https://mainnet-api.inodra.com/v1/billing/plans \
  -H "x-api-key: indr_pat_..."

Prepare the Setup Transaction ​

Returns txBytes (base64). The funder signs and executes it with any Sui SDK or wallet.

bash
curl -X POST https://mainnet-api.inodra.com/v1/billing/onchain/prepare \
  -H "x-api-key: indr_pat_..." \
  -H "Content-Type: application/json" \
  -d '{ "network": "testnet", "tier": "team", "funderAddress": "0x...", "prefundPeriods": 3 }'

Activate the Plan ​

Send the Allowance object ID from the created objects of the executed transaction. allowanceCapId is optional.

bash
curl -X POST https://mainnet-api.inodra.com/v1/billing/onchain/activate \
  -H "x-api-key: indr_pat_..." \
  -H "Content-Type: application/json" \
  -d '{ "network": "testnet", "tier": "team", "allowanceId": "0x..." }'

Read the Plan State ​

Returns the state, the plan, the allowance, the funder, the billing balance, the next charge and the last charges.

bash
curl https://mainnet-api.inodra.com/v1/billing/onchain \
  -H "x-api-key: indr_pat_..."

Change the Plan ​

when is next_renewal or now. An upgrade needs a new allowanceId.

bash
curl -X POST https://mainnet-api.inodra.com/v1/billing/onchain/change \
  -H "x-api-key: indr_pat_..." \
  -H "Content-Type: application/json" \
  -d '{ "tier": "growth", "when": "next_renewal" }'

Cancel the Plan ​

Access continues until the end of the period. Then revoke the allowance from your wallet.

bash
curl -X POST https://mainnet-api.inodra.com/v1/billing/onchain/cancel \
  -H "x-api-key: indr_pat_..."

For billing error codes, see Error Codes.

Error Codes ​

Errors return a JSON body with a code field.

CodeStatusMeaningWhat to do
INSUFFICIENT_SCOPE403The calling key does not have the manage scopeUse a key with manage
SCOPE_ESCALATION403You asked for a scope that the calling key lacksAsk only for scopes that the calling key has
PROJECT_NOT_FOUND404The project is not in your organizationUse a project ID from GET /v1/projects
PROJECT_SLUG_TAKEN409A project with this slug existsUse another name
PROJECT_LIMIT_REACHED403Your plan does not allow more projectsUse an existing project, or upgrade
API_KEY_EXPIRED401The calling key expiredUse another key, or register again
INVALID_SCOPES400An unknown scope nameUse data, streams or manage
INVALID_PROJECT_NAME400The name yields an empty slugUse letters or digits in the name
KEY_NOT_FOUND404No such key in your organizationUse an ID from GET /v1/keys
KEY_LIMIT_REACHED403The organization has 50 enabled keysDisable a key with DELETE /v1/keys/{id}
INVALID_BODY400The JSON body could not be parsedSend valid JSON
AUTH_CONTEXT_MISSING401The key has no organizationUse a key minted for an organization
ORGANIZATION_NOT_FOUND404The organization no longer existsRegister again
UNSUPPORTED_MEDIA_TYPE415The body is not application/jsonSend Content-Type: application/json

Typical Agent Flow ​

  1. Pay with x402.

  2. Call POST /v1/wallet/register when the balance is at least $5. You get a 30-day key with the manage scope.

  3. Use that key to create a key for the workload, with only the data scope. A key never outlives the key that created it, so keys made from a 30-day wallet key expire with it:

    bash
    curl -X POST https://mainnet-api.inodra.com/v1/keys \
      -H "x-api-key: <manage key>" \
      -H "Content-Type: application/json" \
      -d '{ "name": "workload", "projectId": "<project id>", "scopes": ["data"] }'
  4. Use the data key for chain reads. Keep the manage key out of the workload.

  5. Rotate keys before they expire. Do one of these:

    • Call POST /v1/wallet/register again. Inodra issues a new wallet key and revokes the older wallet keys. Keys you created with POST /v1/keys are not revoked; they expire with the wallet key that created them.
    • Create a new key with POST /v1/keys, move the workload to it, then disable the old key with DELETE /v1/keys/{id}.

A person can see the same organization in the dashboard. See See an Agent's Account.

Limits ​

ItemValue
Key lifetime1 to 365 days. Default 30
Default key scopes["data"]
Scopes of a new keyOnly scopes that the calling key has
ProjectsSet by your plan. A wallet organization has one project
Secret visibilityOnly in the 201 response of POST /v1/keys

The full-stack Sui data layer.