---
title: "YouSpot API versioning, deprecation and rate limits"
description: "How the YouSpot API is versioned, what notice you get before anything is removed, the RateLimit headers every limited endpoint answers with, and how Idempotency-Key makes a retry safe."
canonical: https://youspot.com/docs/versioning
last-updated: 2026-09-04
---

# YouSpot API versioning, deprecation and rate limits

> How the YouSpot API is versioned, what notice you get before anything is removed, the RateLimit headers every limited endpoint answers with, and how Idempotency-Key makes a retry safe.

An agent should not have to guess whether the surface it integrated against will still be there next month. This page is the contract.

## Versioning

`/mcp` is the recommended product MCP endpoint and tracks the latest available implementation, currently v1. `/mcp/v1` is supported for clients that explicitly pin v1. Neither endpoint is deprecated. If another major version is introduced, `/mcp` will follow it and the versioned endpoint will remain pinned. `/v1` is the separate agent index. MCP protocol versions are negotiated during initialization, independently of these URL paths.

- Adding an endpoint, a response field, an optional parameter or a new MCP tool is not breaking, and happens without notice.
- Breaking changes to a pinned contract require a new version path. The unversioned `/mcp` endpoint follows the latest implementation; choose a versioned path when you need to stay on a particular major version.
- The OpenAPI document at `/openapi.json` always describes what is live right now.

## Deprecation and sunset

A path being retired announces its deprecation with a `Deprecation` header and a `Link` header with `rel="successor-version"` naming what replaces it. Once a removal date is set, the same responses carry `Sunset` (RFC 8594) as an HTTP-date.

The commitment: at least 180 days between the first `Sunset` header and the path being removed, and a deprecated path keeps working unchanged for that whole window. Watch for the header rather than polling this page.

Deprecated today: the `q` parameter on `/ask`, an alias for `query`. It still works and has no removal date; it is marked `deprecated` in `/openapi.json`.

| Path | State | Purpose |
| --- | --- | --- |
| `/mcp` | Recommended, supported | Latest available implementation (currently v1) |
| `/mcp/v1` | Supported | Explicitly pinned to v1 |
| `/mcp/docs` | Current |  |
| `/mcp/sandbox` | Current |  |

```bash
curl -sD - -o /dev/null https://youspot.com/mcp
# No Deprecation or Sunset header is sent for this supported endpoint.
```

## Rate limits

Every limited endpoint answers with the RFC 9331 headers, so you can pace against the real budget instead of backing off blindly. The dashed triple is sent alongside for clients that parse it.

| Header | Meaning |
| --- | --- |
| `RateLimit` | `"policy";r=<remaining>;t=<seconds to reset>` |
| `RateLimit-Policy` | `"policy";q=<quota>;w=<window seconds>` |
| `RateLimit-Limit` | Requests allowed in the window |
| `RateLimit-Remaining` | Requests left |
| `RateLimit-Reset` | Seconds until the window resets |
| `Retry-After` | On a 429: seconds to wait |

The sandbox MCP server allows 60 calls a minute per address. A 429 is a JSON-RPC error with code -32003 and a `Retry-After` header.

## Idempotency

A dropped connection leaves an agent unable to tell a lost response from a refused request. Send `Idempotency-Key` on a write and the retry is safe: the first answer is replayed rather than the write repeating.

- The key is any unique string up to 255 characters. A UUID is the usual choice.
- A key is scoped to the credential that sent it, so it replays only your own answer. It does not need to be unguessable.
- While `/mcp` serves v1, it shares retry records with `/mcp/v1` for the same credential, key and request body.
- A recorded answer is replayed for 24 hours, with `Idempotency-Replayed: true`.
- The same key with a different request body is a `422`, because that is a client bug rather than a retry.
- Honoured on `POST /oauth/register`, `POST /mcp`, `POST /mcp/v1` and `POST /mcp/sandbox`, and declared on those operations in `/openapi.json`.

```bash
curl -X POST https://youspot.com/oauth/register \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"redirect_uris":["https://example.com/callback"],"client_name":"My agent"}'
```

## Work that outlives one request

A tool that cannot finish inside one call enqueues instead and answers with `task_id`. Poll `GET /api/jobs/<task_id>` until `terminal` is true; while it is still going the response carries `Retry-After` with the interval to use. `result` is filled once `state` is `succeeded`.

```bash
curl https://youspot.com/api/jobs/8412 \
  -H "Authorization: Bearer $YOUSPOT_TOKEN"
# {"job_id":8412,"kind":"file_import","state":"running","terminal":false,...}
```

You can also start one over plain HTTP. `POST /api/jobs` with a `kind` answers `202 Accepted` and a `Location` header naming the job, which is the same URL as `poll` in the body. Starting a kind that is already running reports the running job rather than queuing a second one, so a retry is safe on its own.

```bash
curl -i -X POST https://youspot.com/api/jobs \
  -H "Authorization: Bearer $YOUSPOT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"kind":"embed_objects"}'
# HTTP/1.1 202 Accepted
# Location: https://youspot.com/api/jobs/8413
# Retry-After: 5
```
