Platform API
Separate your customers' agent access and usage within your deep.navy account. Management credentials stay on your backend.
- In API keys, create a Platform management key. Only the signed-in account owner can bootstrap management credentials.
- Create a tenant with your own stable customer reference, then create a tool key for that tenant. Keep the one-time returned secret securely; it cannot be retrieved later.
- Give the tenant tool key to that customer's agent. Use the normal
https://mcp.deep.navy/mcpendpoint. Never distribute the management key. - Read attributed usage from your backend and reconcile it before charging your customers.
Management keys administer tenant keys and usage; they cannot call tools, create other management keys or create account-wide tool keys. Tenant tool keys cannot administer the parent account. A tenant's monitors and budget survive key rotation.
Technical access does not grant blanket resale or content republication rights. Agree commercial terms separately and preserve each source's attribution and restrictions.
POST JSON to the generated Connect service routes with Authorization: Bearer followed by your management key.
Set DEEPNAVY_MANAGEMENT_KEY in your backend environment to the management secret
created in the dashboard. This complete HTTP example creates the tenant; use the same headers
and service origin for the requests below.
curl --fail-with-body --request POST \
'https://api.deep.navy/deepnavy.account.v1.AccountService/CreateTenant' \
--header "Authorization: Bearer $DEEPNAVY_MANAGEMENT_KEY" \
--header 'Content-Type: application/json' \
--header 'Connect-Protocol-Version: 1' \
--data '{"externalRef":"your-customer-42","name":"Customer 42","rateLimitPerMinute":"60","monthlySpendLimitUsdMicros":"10000000"}' CreateTenant returns tenant.id. Pass it as tenantId to CreateApiKey; that response contains key.id, key metadata and
the one-time secret. Give only the tenant tool secret to the agent. A
duplicate externalRef is rejected; use ListTenants to recover your
existing tenant instead of creating another.
https://api.deep.navy/deepnavy.account.v1.AccountService/CreateTenant
{
"externalRef": "your-customer-42",
"name": "Customer 42",
"rateLimitPerMinute": "60",
"monthlySpendLimitUsdMicros": "10000000"
} https://api.deep.navy/deepnavy.account.v1.AccountService/CreateApiKey
{
"name": "Customer 42 agent",
"tenantId": "TENANT_ID_FROM_CREATE",
"management": false,
"rateLimitPerMinute": "30"
} Use Content-Type: application/json and replace the tenant ID placeholder with the
returned UUID. Protobuf JSON represents int64 amounts as decimal strings. One US dollar is 1,000,000
USD micros, so the example tenant cap is $10.
externalRef is unique within your account and immutable. ListTenants and ListApiKeys support pageSize and pageToken;
keys can be filtered by tenantId. Rotate by creating a new key for the same
tenant, switching the client and revoking the old key with RevokeApiKey.
UpdateTenant and UpdateApiKey replace editable settings:
omitting a cap removes it, and zero blocks all tool calls. Setting a tenant's disabled field stops access by all its keys without deleting resources or usage
history.
Per-key and tenant admission limits apply together. Rate limits use fixed UTC minutes; monthly spend budgets use UTC calendar months. Budgets reserve the conservative maximum configured tool-call price before execution, without subtracting free allowances. Failed completed calls release the spend reservation; admitted attempts still consume their minute limit. Unresolved calls remain reserved until reconciled.
These budgets cover synchronous tool calls, not recurring fees, taxes or background monitor deliveries. Keys or tenants with spend caps cannot create, resume or trigger monitors. Rate-only caps apply to synchronous calls and do not limit background monitor execution. A budgeted amount is an enforcement value, not a final invoice total.
These are independent request examples, not a script to run in sequence. Replace the ID
placeholders with returned UUIDs. List requests accept pageSize up to 200;
keep tenantId unchanged while paging keys. Update operations replace all editable
settings, so send every cap you want to retain. There is no separate rotation method: create,
switch and revoke.
AccountService/ListTenants
List tenants. Pass nextPageToken as pageToken to continue.
{
"pageSize": 50
} AccountService/ListApiKeys
List one tenant’s keys, including revocation metadata. This never returns the secret.
{
"tenantId": "TENANT_ID_FROM_CREATE",
"pageSize": 50
} AccountService/UpdateTenant
Disable this tenant’s agent access while keeping its name and existing caps. Set disabled to false to re-enable it.
{
"id": "TENANT_ID_FROM_CREATE",
"name": "Customer 42",
"disabled": true,
"rateLimitPerMinute": "60",
"monthlySpendLimitUsdMicros": "10000000"
} AccountService/UpdateApiKey
Replace the key label and caps. This example removes any existing key spend cap by omitting it; the tenant cap still applies.
{
"id": "KEY_ID_FROM_CREATE",
"name": "Customer 42 agent",
"rateLimitPerMinute": "30"
} AccountService/RevokeApiKey
Revoke the old key after switching the agent to a replacement key for the same tenant. Use key.id, not its prefix or secret.
{
"id": "OLD_KEY_ID"
} The account owner can also create tenants, manage agent keys and edit caps in Dashboard → API keys, and filter usage by tenant/key in Dashboard → Usage.
Tenant ownership and management privilege cannot be changed with UpdateApiKey. Management keys are for tenant provisioning and usage; an
ordinary tool key receives permission_denied here.
Call deepnavy.account.v1.TenantUsageService/GetUsageSummary at the same API
origin with an optional UTC month (YYYY-MM), tenantId and apiKeyId. The response contains month, totals, completionWatermark and observedAt. Totals include successful, failed and pending calls and
budgeted USD micros, with an observation timestamp and completion watermark.
Use TenantUsageService/ListUsageEvents with optional tenant/key filters, limit (up to 500) and pageToken for reconciliation. The response contains events, nextPageToken, hasMore and completionWatermark. Deduplicate by the stable event id; each
event includes apiKeyId, tenantId when scoped, tool, occurredAt, completedAt, outcome, billableUnits and budgetedUsdMicros. A
completed successful call has one billable unit; a completed failure has zero. Events
preserve key and tenant attribution through rotation.
Keep and reuse nextPageToken even when hasMore is false: it is an
incremental polling checkpoint. Tokens are bound to the original filter scope; start a new request
when filters change. Completion ordering handles calls that finish out of order. Store your
checkpoint only after processing the returned events successfully.
Tenant metering covers API-key tool calls admitted after this feature was deployed. Historical usage is not backfilled. OAuth sessions continue through account-level metering and do not appear in this tenant/key event ledger.
Account invoices remain the authoritative charge record. Do not use delayed daily summaries or operational logs as a hard spend gate. See limits and errors and retention.
Usage request examples follow. POST to https://api.deep.navy/deepnavy.account.v1.TenantUsageService/ plus the method name, using the same management headers. The month is illustrative; omit it
for the current UTC month. Event polling has no month parameter. Start without a page token
to consume retained completions, then persist the returned checkpoint.
TenantUsageService/GetUsageSummary
{
"month": "2026-10",
"tenantId": "TENANT_ID_FROM_CREATE"
} TenantUsageService/ListUsageEvents
{
"tenantId": "TENANT_ID_FROM_CREATE",
"limit": 100
} TenantUsageService/ListUsageEvents
{
"tenantId": "TENANT_ID_FROM_CREATE",
"limit": 100,
"pageToken": "NEXT_PAGE_TOKEN_FROM_PREVIOUS_RESPONSE"
} Parse int64 counters and USD micros as exact decimal integers, not floating-point
currency. Poll with the same filters, process and deduplicate the page, then persist its nextPageToken. If hasMore is true, drain the next page; otherwise wait before polling with
that same token. A completion watermark describes committed events, not invoice finality.
Requests and responses follow the ProtoJSON format over the Connect protocol. Preserve source and trust information as described in provenance and trust.