Subcore AI Docs
Agents API

Agent config

The read a running deployment makes on every call. Its payload, its refusals, and the three settings that connect a deployment to it.

GET /agent-config/{routingKey}

Your deployment makes this read on every call an agent takes, between the webhook arriving and the agent answering. It fetches the agent's settings and its stored prompt files, uncached, so an edit made through the agents API is live on the next call.

You do not call it yourself. It is documented here so that the path your prompts take to a call is visible, and so a deployment's logs can be read without guesswork.

Authentication

The deployment sends its own key, the deployment key, as a bearer token. The routing key in the URL identifies the agent; the API key authenticates the caller and confines the answer to its organization and to the cores its permissions.cores reaches. The manage-agents permission is not needed here, and the deployment key does not have it.

A key issued in the console reaches every agent in its organization, so one deployment key serves all of them and a new agent needs nothing added to it. Whether a key may read agents is a single setting rather than a list, so a key that has it turned off is refused for every agent, not for some. That is the 403 below, and it is a key that changed rather than an agent that is missing something.

The payload

{
  "version": 1,
  "agent": {
    "slug": "clinic-one",
    "name": "Clinic One",
    "instructionSource": "database",
    "timezone": "America/New_York",
    "phoneNumber": "+15035550142",
    "transferNumber": "+15035550188",
    "variables": { "clinicName": "Clinic One" }
  },
  "instructions": {
    "main": [
      {
        "path": "instructions.md",
        "content": "…",
        "versionId": "sha256-860e7daee313",
        "updatedAt": "2026-09-16T18:00:21.418Z"
      }
    ]
  }
}
FieldDescription
versionThe dialect of this payload, currently 1. A consumer that does not recognise the version must refuse rather than guess
agentThe agent's settings: the Agent object without routingKey, tenantPath and kind. The caller already holds the routing key it asked on, and the other two answer questions about managing an agent rather than serving a call. variables is here, since prompts are compiled from it
instructionsA map from directory to the stored File objects, content included. Empty for a repo agent

agent.variables is that agent's own prompt variables, which the deployment exposes to its prompts as tenant. followed by each name. It is always an object and {} for an agent with none, so a deployment never has to tell "no variables" from "this payload does not carry them". Reading it needs kit 0.21.1 or later, and an older deployment simply never looks at the field.

versionId is byte-identical to the id the deployment computes for the same file on disk, so a stored file and a repo file can share one provenance record. updatedAt is ISO 8601 UTC with milliseconds and a Z, the same form the File object carries on the instruction routes.

What it answers

CaseAnswer
An agent on repo200 with "instructions": {}, from one indexed lookup. The deployment's own files answer the call
An agent on database with files stored200 with every stored file, read in one statement, so an answer cannot straddle an edit
An agent on database with no file stored409 NO_INSTRUCTIONS, never an empty 200
A routing key that does not exist, is malformed, or belongs to another organizationA bare 404 NOT_FOUND
A key whose permissions.cores does not reach the agent403 FORBIDDEN
A failed query500 DATABASE_ERROR

Every refusal is deliberately unambiguous. An agent that reads its prompts from the database and cannot get them has to fail the call, so that the number's own failover takes over. Nothing here answers with a shape a deployment could read as "carry on with defaults". A missing agent is a bare 404, a database agent with nothing stored is a 409, and a failed read is a 500. The 500 is kept apart from the 404 because a missing agent is permanent and a failed read is not.

No rate limit, no writes

The read is not rate limited, for the same reason telemetry ingestion is not: it sits on a deployment's call path, and a 429 here would fail a live call. It writes nothing, not even the key's last-used timestamp, because it runs inside a voice-latency budget. Every answer is Cache-Control: no-store.

The alias under /api

The same route also answers on

GET /api/agent-config/{routingKey}

That is the path a deployment on kit 0.18.0 builds from its SUBCORE_CONSOLE_URL setting, so a deployment moves its config read to api.subcore.ai by changing that one setting, without a kit release. The alias stays until a kit release reads this service directly.

Connecting your deployment

Three settings in the deployment's environment tie it to this API. The rest of the deployment's configuration is documented with the deployment itself.

SettingValueWhat it does
SUBCORE_API_KEYThe deployment keyAuthenticates the config read and the telemetry the deployment ships
SUBCORE_CONSOLE_URLhttps://api.subcore.aiWhere the config read goes
TELEMETRY_PROFILEstructuralEvents leave the deployment without conversation content
SUBCORE_API_KEY=sk_live_...
SUBCORE_CONSOLE_URL=https://api.subcore.ai
TELEMETRY_PROFILE=structural

The deployment key is not the key that manages agents. It is issued from the deployment's own page in the Subcore console, not from an agent's. It reads configuration and sends telemetry. It cannot manage agents, and it never has the manage-agents permission.

On this page