Skip to content

API changelog for the Mujib REST API

This API changelog lists every change to Mujib’s public REST API (/api/v1) since launch, with its date, newest first. No path and no field name has changed since launch; every change so far concerns errors and the rate-limit headers.

  • The key’s budget on every successful response: X-RateLimit-Limit and X-RateLimit-Remaining on a valid key’s responses now describe that key’s own limit; they could show the per-address limit before. X-RateLimit-Reset now says how many seconds are left until the key’s minute starts over.
  • A 429 from the per-address limit now carries the code RATE_LIMITED, like the key’s own limit, instead of BAD_REQUEST.
  • A malformed id in GET /api/v1/contacts/{id} and GET /api/v1/bookings/{id} now returns a 404 with NOT_FOUND, like an id that does not exist, instead of a 400.
  • Impossible dates are refused with a 400: a day that does not exist in from or to (such as 2026-02-31), a from after to, or an instant in since in the year 0000. An impossible date used to fail with a server error, and a from after to used to return an empty list.
  • GET /api/v1/bookings/{id} now returns a 404 for historical rows imported from an old register, which the list already left out.
  • A 400 for an invalid parameter now lists only the first 20 problems in issues, with issueCount giving the total.
  • The public REST API launched with five requests: GET /api/v1/me, GET /api/v1/contacts, GET /api/v1/contacts/{id}, GET /api/v1/bookings and GET /api/v1/bookings/{id}.
  • Read-only API keys starting with mjb_live_, with two scopes, contacts.read and bookings.read, sent in Authorization: Bearer or X-Api-Key.
  • 60 requests a minute per key, cursor pagination with nextCursor, and one error envelope, { "error": { "code", "message" } }.

Do these changes need anything from my program?

Section titled “Do these changes need anything from my program?”

Usually not, unless your program relied on the old behaviour in one of these cases:

  • If you treated a 400 from a single-item request as “bad id”, treat a 404 the same way.
  • If you told a rate-limit error apart by the code BAD_REQUEST, build on RATE_LIMITED or on the HTTP status 429.
  • If you sent a from after to and expected an empty list, fix the order: the request is now refused with a 400.
  • If you track your remaining budget from the headers, they are now your key’s numbers, and X-RateLimit-Reset tells you when the minute starts over.

Every change is recorded on this page with its date, and the OpenAPI spec carries the date of the latest change in info.version. Compare the date you built against with the current one, and read what lies between them here. Every error code is detailed in API errors and rate limits.

Frequently asked questions

Does this changelog cover dashboard changes?

No. It covers the public REST API only, the requests under /api/v1. The product as a whole has its own changelog in the reference section.

Has the /api/v1 path changed since launch?

No. The same five requests sit at the same paths, with the same fields in their responses.

How do I know the OpenAPI spec matches the latest change?

Its info.version field holds the date of the latest entry in this changelog.