Skip to content

API reference

The reference describes every call you can make with an API key: the request, the response and the statuses you can be answered with. What an administrator does in the console is not in it, because a key does not reach it. Your deployment publishes it in two places, the same content in two forms.

Read it

ReDoc shows the whole API on one page: per route the parameters, the request schema, every response and the fields inside it. Use this form to look up what a route expects and what comes back. Its request examples are addressed to the Core your deployment published this guide with.

Try it out

Swagger UI covers the same routes and also calls them. It calls the address in its Servers field, which your deployment fills in: check that it is the address your key was issued for and change it if it is not. Then click Authorize, paste your key's secret and choose Try it out on a route. The answer you see comes from your own deployment. Your key works there only because this is your deployment's own guide page: a key sent from any other web page is refused (A token for the browser).

The contract itself

/api/openapi.json is the OpenAPI document both pages run on. Use it to generate a client in your own language.

Base URL

Every route in this reference is called at one address: the address of your deployment, followed by /api/v1.

https://<your-deployment>/api/v1

<your-deployment> is the host your API key was issued for. Your organisation's administrator can tell you which one that is. For Artific's development environment the base URL is https://build.dev.artific.nl/api/v1.

Where this guide writes a route as GET /key, you call the base URL with that path behind it:

curl -s "https://<your-deployment>/api/v1/key" -H "Authorization: Bearer ack_..."

GET /key returns your key's organisation, capabilities and policy and changes nothing, so it checks an address and a key in one call. The other examples in this guide keep the base URL in CORE_URL and the secret in CORE_KEY, which Make your first call sets.

This guide has the same text on every deployment, so its pages write the placeholder. The two explorers above do show your deployment's own address. Swagger UI shows it in its Servers field, without /api/v1, because every path it lists already begins with it. ReDoc shows it when you open a route's method and path, as the full address of that route.

One client takes a shorter address. Anthropic's client appends /v1/messages itself, so its base_url ends at /api; see Using the Anthropic SDK.

Using the OpenAI SDK

POST /responses answers the OpenAI Responses object, so the official openai client reaches Core unchanged: point base_url at your deployment's /api/v1 and hand it your key's secret as api_key, which it sends as the bearer token above. Errors come back in OpenAI's own envelope too, so openai.APIStatusError carries the message, the param naming the field and the code.

from openai import OpenAI

client = OpenAI(base_url="https://<your-deployment>/api/v1", api_key="ack_...")
response = client.responses.create(model="<your-model>", input="Hello", store=True)
print(response.output_text, response.conversation.id)

Three things are worth knowing. conversation is the thread the turn was stored on, and it is the same id the threads routes take. A tool Core runs for you comes back as an mcp_call item, which is what the Responses API calls a tool the server ran on your behalf; a function tool you execute yourself comes back as a function_call, exactly as upstream. And a field of OpenAI's that Core does not act on is handled in one of three ways. A hint that does not change what the answer means — service_tier, include, prompt_cache_key — is accepted and ignored. A field a model provider can take — top_p, parallel_tool_calls, a forced tool — is passed on, and refused 400 by name where the model you named cannot take it. A field Core cannot honour — truncation: "auto", a hosted tool type such as web_search — is refused 400 by name, so a call that succeeds never means less than you wrote. Connect a coding agent lists the fields in each class.

A stored agent is reachable without any extra body field: pass agent:<name> (or its agt_ id) as model, and client.models.list() lists the agents your key can use beside the models. Your instructions are sent ahead of the agent's, and response.model is the model the agent ran.

response = client.responses.create(model="agent:triage", instructions="Be brief.", input="Hi")

The SDK's own types do not declare Core's extensions to the body. Pass a tool Core runs, tools=[{"type": "tool", "name": "..."}], as a plain list or through extra_body, and a field such as helper through extra_body: extra_body={"helper": "acme.summary"}.

Authentication

Every route outside the administration routes expects your API key's secret as a bearer token:

Authorization: Bearer ack_...

See Make your first call for getting a key and sending your first request.

Using the Anthropic SDK

Core answers Anthropic's Messages API at /api/v1/messages, so Anthropic's own client reaches it unchanged. Point it at your deployment and give it your key's secret as api_key, the way Anthropic's own examples do; auth_token works too, and sends the same secret as a bearer token:

import anthropic

client = anthropic.Anthropic(base_url="https://<your-deployment>/api", api_key="ack_...")
message = client.messages.create(
    model="<a model your key may use>",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Summarise this week's tickets."}],
)

The answer is Anthropic's message object. A field Core cannot honour — mcp_servers, container, a fixed thinking.budget_tokens and a few more — is refused by name instead of ignored, so a request never quietly means less than you wrote. top_p, top_k, stop_sequences and a forced tool are passed on to the model; where the model you named cannot take one, the refusal names that field. A hint that does not change what the answer means, such as cache_control or the anthropic-beta header, is accepted and ignored (Connect a coding agent). The id you get back is a Core response id: the same value works on GET /responses/{id} and on GET /artifacts?response_id=.