Skip to the content
  1. Docs
  2. Get started

Rate limits and errors

Core + Managed TransfersGuide · 3 min
The rate limit of a partner account, the error shape, the internal error codes, and what to do on a 412 or a 429.

Rate limit

Each partner account has one rate limit for all its keys and credentials together.

  • 300 requests per minute by default.
  • One fixed 60-second window. The first request starts the window, and the count resets 60 seconds later.
  • Over the limit, the API answers 429 Too Many Requests with Retry-After: 60. The header gives the window length in seconds, not the time left in the window.
  • The limit counts calls to /public/* and /api/*. The hosted sign-in pages and webhooks do not count.
  • Need more? Contact us. We can raise the limit of your account or remove it.

A docs sandbox session has its own limit: 30 calls per minute.

429 answer
{
  "message": "MusicAPI rate limit. You have exceeded the rate limit for this endpoint or server is currently unable to handle the request. Please wait and retry after the indicated time."
}

Handle a 429

async function callMusicApi(url, init, attempt = 0) {
  const response = await fetch(url, init);
  if (response.status !== 429 || attempt >= 3) {
    return response;
  }
  const waitSeconds = Number(response.headers.get("retry-after") ?? "60");
  await new Promise((resolve) => setTimeout(resolve, waitSeconds * 1000));
  return callMusicApi(url, init, attempt + 1);
}

Spread bulk work over time instead of sending it in bursts. A music service can also refuse a call because of its own limits. Retry such a call later, with a growing pause.

The error shape

Every error answer is JSON.

An API error
{
  "internalCode": 14,
  "message": "Needs reauthentication",
  "sentryId": "b6f1c2d4e5a64f0f9a1b2c3d4e5f6a7b"
}
FieldWhat it is
messageA short text. Show it in your logs, not to your users.
internalCodeA number for the cases worth branching on (table below). Not every error has one.
detailsMore detail, when there is any.
sentryIdOur error id. Send it to us when you report a problem.

A body or query that fails validation answers 400 with the field that is wrong:

400 validation error
{
  "type": "body",
  "message": "\"itemIds\" must contain less than or equal to 20 items",
  "details": [{ "message": "\"itemIds\" must contain less than or equal to 20 items", "path": ["itemIds"] }]
}

Status codes

StatusMeaningWhat to do
400The request is not valid.Fix the request. Do not retry it unchanged.
401No credential, or a credential this route does not read.Check the Authorization header and the route table.
403The credential is valid but not allowed here, or an evaluation account reached its cap.Use a Client Secret where the route needs one.
404The connected user, item or transfer does not exist in your account.Check the id. Another account's id also answers 404.
412The user must sign in again.Send the user through the hosted sign-in.
418The service does not support this operation.Check Services and features.
422The item is already in the collection.Treat it as done.
429Rate limit.Wait Retry-After seconds.
5xxOur error, or the music service failed.Retry later with a growing pause.

Internal error codes

internalCodeNameStatus
12InvalidReturnUrl: the returnUrl is not one of your Accepted Return URLs400
14IntegrationUserNotAuthenticated: the stored sign-in no longer works412
15NotSupportedMethod: the service has no such operation418
18ItemAlreadyExistsInCollection422
19CollectionDoesNotExists: the playlist or album is gone, or cannot be read404
20ManualLoginRequired: the user must sign in on the service's own site first403
21ActionInMusicServiceRequired: the user must do something in the service first, for example accept new terms403

The user must sign in again (412)

A 412 with internalCode: 14 means the music service refused the stored sign-in, and MusicAPI could not renew it. The user changed their password, removed your app, or the refresh token expired.

412 answer
{
  "internalCode": 14,
  "message": "Needs reauthentication"
}

What to do:

  1. Mark the connection as broken in your app.
  2. Show the user a "Reconnect" button that opens the hosted sign-in for the same service.
  3. When the same music account signs in again, it keeps its integrationUserUUID. Your stored id stays valid.

Before it answers 412, MusicAPI already tried to renew the tokens once. Do not retry the call in a loop.