Skip to main content

// api reference

Every endpoint, every shape, every example.

The Magistry REST API is one base URL, three auth modes, and eight endpoint groups. Versioned by date header, idempotent on every write, and signed HMAC-SHA256 on every webhook delivery.

api.magistry.io OAuth2 + service JWT Date-pinned versioning

// auth

Three modes. Pick one per token, never mix.

OAuth2 for human operators in the dashboard, service-account JWTs for worker-to-worker, and HMAC-SHA256 for inbound webhook signatures. Every call is over TLS 1.3, every token is workspace-scoped, every secret rotates from the dashboard with zero downtime.
human · dashboard

OAuth2

Authorization-code flow with PKCE. Short-lived access tokens (15 min) and rotating refresh tokens (30 days). Scopes line up 1:1 with endpoint groups — decisions:read, campaigns:write, etc.

Authorization: Bearer at_…
worker-to-worker

Service-account JWT

RS256-signed, 60-minute TTL, audience-bound to api.magistry.io. Issued from the workspace dashboard, scoped per service. Rotate the key, the old JWT dies in seconds.

Authorization: Bearer eyJhbGc…
inbound webhooks

HMAC-SHA256

Every delivery includes a timestamp + signature header. Reject deliveries older than 5 minutes; verify the HMAC over ts.body before you trust the payload. Replays drop on a per-id idempotency cache.

X-Magistry-Signature: t=…,v1=…

// endpoint groups

Eight groups. Every shape stable for a year.

Every endpoint is grouped by surface. Within a group, every list endpoint paginates by opaque cursor, every write accepts an Idempotency-Key, and every error returns the same JSON envelope.
GET

/decisions

Read the append-only ledger. Every action lands here as a row.

/v1/decisions
GET

/products

Catalog state, lifecycle, cost confidence tier, last cycle action.

/v1/products/{variant_id}
PATCH

/campaigns

Google Ads + Meta + TikTok + Bing — read state, request budget shifts.

/v1/campaigns/{id}/budget
GET

/cs/threads

Inbound + outbound threads, brand-voice draft, escalation queue.

/v1/cs/threads
POST

/disputes

Chargeback rows, evidence chains, Ethoca/Verifi/RDR responses.

/v1/disputes/{id}/respond
GET

/research/candidates

Six discovery lanes — trend, supplier, repeat-buyer, geo, gap, refresh.

/v1/research/candidates
POST

/jobs

Worker job state — submit a dry-run cycle, poll for completion.

/v1/jobs
POST

/webhooks

Register an HMAC-SHA256-signed URL to receive decision row events.

/v1/webhooks

// example

One request. One row. Pasted from production.

Below is a real shape — same field names, same envelope, same headers as you'll get back on a live workspace. Send the request; iterate the cursor; you have a tail of the decision log.
requestGET
GET /v1/decisions?store_id=stk_2YHFZ3WkP6e3xL2&since=2026-05-25T00:00:00Z
Host: api.magistry.io
Authorization: Bearer sk_live_a8f3…2b91
Accept: application/json
X-Magistry-Version: 2026-05-01
response200 OK
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Remaining: 597
X-Magistry-Cycle: cyc_771

{
  "data": [
    {
      "id":          "dec_01J9X2KQZP6E3XL2",
      "agent":       "catalog",
      "action":      "DISCOUNT_TEST",
      "subject":     "SKU-LIN-228-SND-L",
      "from_state":  "ACTIVE",
      "to_state":    "ON_DISCOUNT",
      "judge_score": 0.88,
      "tier":        "A",
      "evidence":    ["perf#9123", "cycle#771"],
      "reversal":    "PRICE_RESTORE@2026-06-08",
      "applied_at":  "2026-05-25T08:02:14Z",
      "applied_by":  "catalog_agent.discount_executor"
    }
  ],
  "next_cursor": "cur_2YHFZ3WkP…",
  "has_more":    true
}

// rate limits

Hard caps, soft bursts, headers on every reply.

Every response carries `X-RateLimit-Remaining` and `Retry-After` (when relevant). Hit a cap and the API returns 429 with a JSON envelope describing the bucket and the cooldown. Bulk and discovery are metered separately so they don't starve your reads.
ScopeSustainedBurstWindow
Read600 req / min1,000 req / 10sPer workspace token
Write60 req / min120 req / 10sPer workspace token
Webhook deliveryUp to 50 / sBackpressure at 200 in-flightPer registered endpoint
Bulk export4 jobs / hour1 concurrent jobPer workspace
Discovery (Researcher)20 candidates / min60 candidates / 10sPer lane

// sdks

Two stable. Two in beta. All generated from one spec.

Every SDK is generated from the same OpenAPI document the API itself validates against — no drift, no surprise field names, no per-language casing fights.
PythonStable

First-party. Same library the FastAPI worker uses in production.

pip install magistry-sdk
TypeScriptStable

Edge-ready, fetch-based. Generated from the same OpenAPI as Python.

npm i @magistry/sdk
GoBeta

Reads stable, writes still under review. Tag v0.9.x — pin it.

go get github.com/magistry/magistry-go
RubyBeta

Reads + webhook helpers. Catalog/campaign writes land in v0.10.

gem install magistry

// status + policy

If we break it, we date it.

Every breaking change ships behind a date-pinned version header. Old shapes stay live for 12 months. Status is published on the public dashboard with five-minute resolution.

API status

All systems nominal

Live status, current incident, and the last 90 days of uptime live at /support/status. Subscribe by email or RSS to get incidents in your inbox the moment they open.

  • 99.98% uptime, trailing 90 days
  • p95 187 ms read latency from EU edge
  • p95 412 ms write latency end-to-end

Breaking-change policy

Breaking changes ship behind a new date-pinned version header (e.g. X-Magistry-Version: 2027-01-01). The previous shape stays live in parallel for a full 12 months before deprecation.

  • 90 days written notice on the changelog + email
  • Migration guide with a diff per endpoint
  • Deprecation header (Sunset:) on every call

// api reference

Magistry runs your store. We run Magistry.

The API is the same surface our worker pushes through in production. Same auth, same rate limits, same row shape as your dashboard.

OAuth2 + service JWT · HMAC-SHA256 webhooks · Date-pinned versioning