Connect an assistant

Server-side access

Call reports from your own backend with OAuth client credentials. No API key, no browser, no human in the loop.

Server-side access

Everything here works from a backend service with no human present. If you are wiring reports into your own dealership platform, DMS, or internal tool, this is the page you need.

There are no API keys, and what to use instead

AI Desk does not issue API keys. It issues OAuth client credentials, which is the standard machine-to-machine grant and does the same job: a client id and a client secret your server holds, exchanged for a short-lived token.

If you already hold a MarketCheck API key for the data endpoints, note that it is a different system and does not work here. AI Desk is a separate account with a separate balance.

One thing to rule out early: the REST endpoint the web app uses to run a report authenticates off a browser session cookie, so it cannot be called server to server. The MCP endpoint below is the supported path, and despite the name it is an ordinary JSON over HTTPS POST. No AI client is involved.

Step 1: create an agent

An agent is a machine identity that belongs to your team and spends your team's balance under limits you set.

Go to Agents and create one. You choose:

Setting What it does
Scopes Which reports this agent may run. Grant only what it needs
Per-call maximum Refuses any single call priced above this
Daily cap Total spend per day
Monthly cap Total spend per calendar month
Webhook URL Optional. Receives report.completed and wallet.debited events

Set the caps. An unattended service that loops is the realistic failure mode, and a monthly cap is the cheapest insurance against it.

You are shown a client id and a client secret. The secret is shown once. Store it the way you store any other production credential.

Step 2: get a token

curl -X POST https://ai.marketcheck.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "scope=reports:window-sticker"
{
  "access_token": "eyJhbGciOi...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "reports:window-sticker"
}

Credentials may go in the body as shown, or in an HTTP Basic authorization header. Either is accepted.

Three things to build around:

Step 3: run a report

curl -X POST https://ai.marketcheck.com/mcp \
  -H "Authorization: Bearer eyJhbGciOi..." \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "generate_window_sticker",
      "arguments": { "vin": "1GNSKBKC5MR123456" }
    }
  }'

The tool name and its arguments are listed on each report's page in the catalog.

Step 4: read the response

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{ "type": "text", "text": "{ ...report JSON as a string... }" }]
  }
}

content[0].text is a JSON string, not an object. Parse it. This is the single detail that costs integrators the most time.

Parsed, it contains:

{
  "data": {
    "executive_summary": { "headline": "...", "verdict": "...", "key_metrics": [] },
    "window_sticker": { "pdf_url": "https://ai.marketcheck.com/api/window-sticker/9f2c...", "format": "PDF (11x17 landscape)" },
    "vehicle": { "vin": "..." },
    "hosted_report": { "url": "https://ai.marketcheck.com/r/..." }
  },
  "billing": {
    "list_price_usd": 1.99,
    "charged_usd": 1.99,
    "balance_after_usd": 248.05,
    "report": "Window Sticker"
  }
}

Every run reports its own cost and the balance left. Log balance_after_usd and alert on it, so a stalled balance surfaces before it stops your service.

Step 5: fetch artifacts

Reports that produce a file return a URL rather than bytes.

curl -H "Accept: application/pdf" "PDF_URL" -o sticker.pdf

Adding ?format=pdf does the same thing. Open the same URL in a browser instead and it renders in a viewer with download and print controls.

Artifact and hosted-report links are unguessable but public. Anyone holding the link can open it. Treat them like share links: fine to email to a customer, not a substitute for access control.

Errors

Response Meaning What to do
invalid_client Unknown client id, wrong secret, or the agent is revoked Check the credential. Re-issue if revoked
401 with a WWW-Authenticate header Token missing, expired or rejected Fetch a new token
Result text says the connector lacks access The scope was not granted to this agent Add the scope on the agent
Result text names a balance below the price Not enough balance Top up, or enable auto top-up
isError with a failure message The run failed Nothing was charged. Safe to retry

A failed run is never billed. This matters for retry logic: you can retry without worrying about double charges.

Keeping an unattended service running

Enable auto top-up. A service that stops at a zero balance at 2am is the most common way this integration fails. Set a threshold and an amount so the balance refills itself.

Watch your caps. A daily or monthly cap doing its job looks identical to a broken integration. Alert on cap-refusal responses so you can tell the two apart.

Revocation is immediate. Revoking an agent takes effect on the next call, not when its current token expires, because the agent's status is re-checked on every request.