> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apostra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# V3 HTTP API

> Call account-aware Apostra operations over fixed HTTP routes and generate a typed client from OpenAPI 3.1.

Every public v3 operation has a fixed route:

```text theme={null}
POST https://api.apostra.com/api/v3/tools/<operation>
```

The HTTP API publishes a separate, stricter wire contract for the public v3
operation catalogue. HTTP and v3 MCP use the same account permissions and
guarded business handlers, but their request schemas are not always identical.
Use the OpenAPI 3.1 document for HTTP clients and `tools/list` for MCP clients.
HTTP is useful for scheduled jobs, backend services, and applications that
choose an operation in code rather than through model tool discovery.

<Note>
  The V3 REST API is available to authenticated Buyer and Seller accounts. Its
  OpenAPI 3.1 document is available at
  `https://api.apostra.com/api/v3/openapi-3.1.yaml`.
</Note>

One intentional compatibility difference is Creative search. HTTP
`search(kind: "creative")` requires `filter` to contain exactly one of
`advertiserId` or `campaignId`. The MCP/runtime parser rejects both owners but
permits neither so a Seller can receive the contextual
`OWN_SUPPLY_SCOPE_REQUIRED` guidance. An ownerless Creative search is therefore
valid at the MCP parser boundary and invalid at the HTTP boundary.

## Make a request

Send an API key or M2M access token as a bearer credential. The JSON request
body is the operation input.

```bash theme={null}
curl https://api.apostra.com/api/v3/tools/get_status \
  --request POST \
  --header "Authorization: Bearer $APOSTRA_API_KEY" \
  --header "Content-Type: application/json" \
  --header "X-SCOPE3-CUSTOMER-ID: $APOSTRA_CUSTOMER_ID" \
  --data '{}'
```

Omit `X-SCOPE3-CUSTOMER-ID` when the credential already resolves to one
account. Supplying the header never expands the credential's account access.

## Retry a write

Send an `Idempotency-Key` header with every V3 HTTP write request. Use the same
key and the same validated body to retry after a lost response. For seven days
after a write settles, that retry replays the typed result; changing the body
with the same key returns `409 CONFLICT`. After seven days the completed receipt
and result are removed, and the key may name a new write. Do not reuse it unless
that new write is intentional.

An in-flight or uncertain receipt does not expire. Retry the same operation,
key, and body to receive `202 Accepted` and `Retry-After` while recovery
continues. Do not mint a new key for an uncertain receipt.

Some operations also accept `idempotencyKey` in their JSON body. When that
field is present, it must exactly match `Idempotency-Key`; the API never uses
two different keys for one write.

For `save_billing`, `paymentAuthority.action: "status"` is a read-only poll.
It requires `interchange:read`, an exact credential-to-organization match, and
no advertiser scope. It returns status and expiry, never card details or the
capture-link URL. A child-bound credential cannot use inherited parent billing
access. Requesting or confirming payment authority remains an
`interchange:write` operation. See [Authentication](/v3/authentication#payment-authority-status-access)
for the member and inherited-account rules.

## Handle the response

A successful call returns the operation's typed result in `data`:

```json theme={null}
{
  "data": {
    "account": {}
  },
  "error": null
}
```

A non-2xx response returns an ADCP error in `error`:

```json theme={null}
{
  "data": null,
  "error": {
    "code": "ACCESS_DENIED",
    "message": "This operation is not available to the selected account."
  }
}
```

HTTP responses do not contain MCP `content`, `_meta`, or `isError` fields. Use
the status code for transport handling and the error `code` for recovery.
Unexpected server failures use a scrubbed `INTERNAL_ERROR` message.

Each HTTP operation has a 210-second route deadline, below the REST transport's
240-second limit. A write can return `503 SERVICE_UNAVAILABLE` only before the
API durably claims its receipt and before dispatch starts. Once claimed, a
deadline or closed connection leaves the receipt in flight or uncertain; a
connected caller receives `202 Accepted` and `Retry-After`, while the API keeps
settling a completed dispatch in the background. The route does not try to
send a response to a closed socket.

## Generate a client

The generated OpenAPI 3.1 document is available at:

```text theme={null}
https://api.apostra.com/api/v3/openapi-3.1.yaml
```

It will contain the fixed public operation routes, strict request and success
schemas, typed non-2xx error bodies, API key and M2M security schemes, and the
existing v3 document routes. Operation IDs match the operation names so
generated client methods remain stable.

Each public operation owns a separate HTTP input contract. The contract
describes types, closed object shapes, required fields, and conditional request
branches such as create versus update. The HTTP route validates that contract
before it dispatches the operation, and generated clients expose those branch
types.

Some checks depend on values or current server state and cannot be promised by
an SDK type. Examples include optimistic revisions, cursor provenance,
cross-field value equality, normalized uniqueness, calendar arithmetic, and
resource ownership. Those checks run after structural validation and return a
typed `422` error when the request is structurally valid but cannot be applied.
The OpenAPI document does not claim that client construction proves those
business rules.

The existing `/api/v3/openapi.yaml` document remains the OpenAPI 3.0 contract
for the two v3 document resources. Integrations that need the fixed operation
routes must use the versioned OpenAPI 3.1 URL above.

The v2 API remains supported. Existing integrations do not need to migrate,
and APIs outside the public v3 operation catalogue continue to use v2.

## Official SDKs

Start with the [SDK quickstart](/v3/sdk-quickstart) for installation, account
discovery, campaign launch preview and delivery reporting. See the [TypeScript
and Python SDK guide](/v2/sdk) for paired publication status, generated models,
account targeting and transport conventions.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.