---
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

The API is versioned in the URL path. `/mcp/v1` is the current product MCP server and `/v1` is the agent index. A version never changes meaning underneath you: a breaking change gets a new path, not a new shape at the old one.

- Adding an endpoint, a response field, an optional parameter or a new MCP tool is not breaking, and happens without notice.
- Removing or renaming a field, tightening a type, or removing an endpoint or tool is breaking, and only ever happens at a new version path.
- The OpenAPI document at `/openapi.json` always describes what is live right now.

## Deprecation and sunset

A path being retired answers with `Deprecation: true` (RFC 9745) 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.

| Path | State | Use instead |
| --- | --- | --- |
| `/mcp` | Deprecated, no sunset date set | `/mcp/v1` |
| `/mcp/v1` | Current |  |
| `/mcp/docs` | Current |  |
| `/mcp/sandbox` | Current |  |

```bash
curl -sD - -o /dev/null https://youspot.com/mcp
# Deprecation: true
# Link: <https://youspot.com/mcp/v1>; rel="successor-version"
```

## 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.
- 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/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,...}
```
