Agentic Workforce ME Developer PortalDocs 1.1 · Widget 0.1.0

Backend integration

API keys & authentication

Creating and rotating API keys, roles and tenant scoping, the base URL, RFC 9457 errors and rate limits.

Every call your backend makes to Agentic Workforce ME carries two headers: a tenant API key and the tenant id. Both are checked before any route runs; every table is tenant-scoped with row-level security, so a key can never read or write another tenant.

Shell
# Every platform call: bearer API key + the tenant id
curl https://console.agenticworkforce.me/v1/agents?limit=5 \
  -H "Authorization: Bearer $HIVE_API_KEY" \
  -H "X-Tenant-Id: $HIVE_TENANT_ID"

API keys

  • Authorization: Bearer hive_… — create one in the console (Settings → API keys) or with POST /v1/api-keys. The secret is shown once; the platform stores a hash.
  • X-Tenant-Id: <uuid> — the tenant the key belongs to. A key presented with another tenant’s id is rejected with the same 401 UNAUTHORIZED as an unknown key: the key is looked up inside the tenant you named, so the API cannot tell — and deliberately does not reveal — that it exists elsewhere. Without the header the call is a 400 TENANT_REQUIRED.
  • last_used_at is updated on every authenticated call, which is how you find keys that are safe to revoke.
Shell
# Mint a dedicated key for the integration (admin). The secret is shown once.
curl -X POST https://console.agenticworkforce.me/v1/api-keys \
  -H "Authorization: Bearer $HIVE_ADMIN_API_KEY" \
  -H "X-Tenant-Id: $HIVE_TENANT_ID" \
  -H "Content-Type: application/json" \
  -d '{"name":"orders-service"}'
# → 201 { "id": "…", "name": "orders-service", "prefix": "hive_ab12…", "secret": "hive_…" }

Roles: what a key may do

Routes are gated by member role (member < admin < owner). An API key always acts as admin: it can read and mutate every tenant resource this section uses (agents, workflows, triggers, MCP servers, connections, tool grants, approval policies, webhooks, other API keys), and it can decide approvals assigned to member, admin or manager. Owner-only routes and owner-assigned approvals return 403. There are no narrower scopes on a key today — if you need least privilege between services, create one key per service and keep them apart in your secret manager.

In the audit log a key appears as apikey:<key id>, so the actor of every provisioning call and approval decision made by your backend is attributable to the key you created for it.

Rotation

  1. Create the new key and store its secret.
  2. Deploy the new secret to your service; confirm calls succeed.
  3. DELETE /v1/api-keys/:id on the old key. Revocation is immediate; in-flight requests with the old key start failing with 401 UNAUTHORIZED.

Base URL and conventions

  • Base URL: your deployment’s API origin (in these docs https://console.agenticworkforce.me). All resources live under /v1; the one exception is the public hook endpoint /hooks/:triggerId, which authenticates with an HMAC instead of a key.
  • JSON request bodies (Content-Type: application/json); ids are UUIDs (v7); timestamps are ISO 8601 in UTC.
  • Lists paginate with ?cursor=&limit= (default 25, max 100) and return { items, next_cursor }.
  • GET /v1/openapi.json is the live OpenAPI document; the TypeScript SDK types are generated from the same Zod DTOs the API validates with.

A client in your language

hive.tsTypeScript
import { HiveClient } from '@hive/sdk';

export const hive = new HiveClient({
  baseUrl: process.env.HIVE_API_URL!,      // https://console.agenticworkforce.me
  apiKey: process.env.HIVE_API_KEY!,       // hive_… (server-side only)
  tenantId: process.env.HIVE_TENANT_ID!,   // the tenant the key belongs to
});

Errors (RFC 9457)

Every error is an application/problem+json document with a stable machine-readable code. Branch on code, show detail to a developer, never parse title.

HTTP
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json

{ "type": "about:blank", "title": "Requires admin role", "status": 403, "code": "FORBIDDEN" }

HTTP/1.1 400 Bad Request
Content-Type: application/problem+json

{ "type": "about:blank", "title": "Bad Request", "status": 400, "code": "VALIDATION",
  "detail": "events: Too small: expected array to have >=1 items; url: Invalid URL" }
CodeStatusMeaningWhat to do
UNAUTHORIZED401Missing, revoked or unknown API key (or no session) — including a live key presented with another tenant’s X-Tenant-Id: the key is looked up inside that tenant, so the API cannot tell (and deliberately does not reveal) that it exists elsewhere.Send Authorization: Bearer hive_… with a live key of the tenant in X-Tenant-Id.
TENANT_REQUIRED400API key calls need the tenant id.Add X-Tenant-Id: <tenant uuid>.
FORBIDDEN403Role too low for the route or the approval.Admin routes need an API key or admin/owner session; owner-assigned approvals cannot be decided with a key.
VALIDATION400Body or query failed Zod validation.Read detail: <field path>: <message> pairs separated by ; (for example agent_id: Invalid UUID).
NOT_FOUND404Unknown id in this tenant (also every unknown/disabled hook URL).Check the id and the tenant header.
RATE_LIMITED429Per-tenant token bucket exhausted.Honour Retry-After (seconds); spread bursts.
INVALID_SIGNATURE401Hook HMAC does not match the raw body.Sign the exact bytes you send; check the secret and the sha256= prefix.
INVALID_BODY400Hook body is not JSON.Send a JSON object with Content-Type: application/json.
AGENT_NOT_PUBLISHED409The target agent has no published version.Publish the draft (POST /v1/agents/:id/versions/:v/publish).
WORKFLOW_NOT_PUBLISHED409The target workflow has no published version.Publish it (POST /v1/workflows/:id/versions/:v/publish).
TRIGGER_DISABLED409Manual fire of a paused trigger.Enable it with PATCH /v1/triggers/:id.
SLUG_TAKEN409Slug already exists in the tenant.Pick another slug or reuse the existing resource (idempotent provisioning).
INVALID_URL422Webhook URL rejected by the SSRF guard.Use https and a public host; for local testing expose a tunnel URL.
ALREADY_DECIDED409Approval is no longer pending or you already decided it.Treat as success if your decision matches; otherwise read the approval.
INVALID_ARGS422edited_args on an edit decision failed the tool’s JSON Schema.Read detail; send arguments the tool schema accepts (or approve/reject instead).
MCP_UNREACHABLE502The platform could not connect to your MCP server or list its tools.Check the endpoint is reachable from the platform’s worker, the bearer credential, and the SSRF allow-list for local hosts.

Rate limits

A token bucket per tenant (per client IP when no tenant header is present) with a default capacity of 120 requests refilled at 20 per second (deployment-configurable). When it is empty you get 429 RATE_LIMITED with a Retry-After header in seconds and the same value as retry_after in the body. Sustained throughput above 20 requests/s from one service is a sign to batch (bulk approval decisions, list endpoints with limit=100) rather than retry harder.

HTTP
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 1

{ "type": "about:blank", "title": "Too Many Requests", "status": 429, "code": "RATE_LIMITED",
  "detail": "Per-tenant request rate limit exceeded.", "retry_after": 1 }

Some self-serve routes carry stricter scoped buckets (their detail names the scope). Health probes are never limited. The hook endpoint and SSE streams count like any other request when they start; an open SSE connection does not consume tokens while it streams.

API key endpoints

GET/v1/api-keysList the tenant’s API keys (prefix only — never the secret).
Auth
API key + X-Tenant-Id (tenant admin)
Errors
UNAUTHORIZED TENANT_REQUIRED FORBIDDEN

Response

FieldTypeDescription
items[].iduuidKey id (use it to rename / revoke).
items[].namestringDisplay name.
items[].prefixstringDisplay prefix such as hive_ab12… — enough to recognise a key.
items[].last_used_atISO date-time | nullUpdated on every authenticated call.
items[].revoked_atISO date-time | nullSet once revoked; revoked keys stop authenticating immediately.
POST/v1/api-keys201Create a key. The secret is returned exactly once.
Auth
API key + X-Tenant-Id (tenant admin)
Errors
UNAUTHORIZED TENANT_REQUIRED FORBIDDEN VALIDATION

Request

FieldTypeDescription
namestringDisplay name (1–120).

Response

FieldTypeDescription
iduuidKey id.
secretstringThe full hive_… secret. Store it in your secret manager now — it is hashed at rest and never shown again.
prefixstringDisplay prefix.
  • Audited as api_key.create.
PATCH/v1/api-keys/:idRename a key.
Auth
API key + X-Tenant-Id (tenant admin)
Errors
UNAUTHORIZED TENANT_REQUIRED FORBIDDEN NOT_FOUND

Request

FieldTypeDescription
namestringNew display name.
  • Audited as api_key.rename. A revoked key returns 404.
DELETE/v1/api-keys/:id204Revoke a key (204). Rotation = create the new key, switch, revoke the old one.
Auth
API key + X-Tenant-Id (tenant admin)
Errors
UNAUTHORIZED TENANT_REQUIRED FORBIDDEN NOT_FOUND
  • Audited as api_key.revoke.