Authentication & Rate Limits
Authentication
The Integrations API uses the same Butlr login system as the rest of the Butlr API; there is no separate login. It accepts client-credentials tokens only:
Which token: use the OAuth 2.0 Client Credentials Grant described in Authentication. Mint client credentials, then exchange them at
POST https://api.butlr.io/api/v2/clients/loginwith"audience": "https://butlrauth/".What doesn't work: user tokens from the password login (
POST /api/v2/login) work with the GraphQL and Reporting APIs but are rejected here with401/-3.
Send the token on every request:
Authorization: Bearer [insert access_token here]Every query is scoped to the Butlr client ID carried in the token, so you only ever receive your own data.
Authentication failures return one of these:
401
-3
Token missing, expired, not valid, or not accepted by this API (for example a password-login token)
400
-2
Token is malformed and cannot be parsed
400
-5102
Token carries no usable client ID
{ "errors": [{ "code": -3, "description": "jwt_invalid_error=…" }] }If you get -3, first check that you are using a client-credentials token, not a password-login token; retrying won't fix that. A -3 can also occur briefly if Butlr cannot verify your client at that moment, so if the token is right, retry after a short wait.
Rate limits
Requests are limited per client with a token bucket:
Burst: up to 30 requests at once.
Refill: 1 request per second (60 per minute). After a burst, you can send one more request each second.
A client that sends no more than one request per second is never limited. Over the limit, the API returns 429 Too Many Requests with code -5200 and a Retry-After: 60 header. You don't have to wait the full 60 seconds: capacity returns at one request per second.
One request can ask for several measurements at once (see Combining measurements), which is usually cheaper than making several calls.
Calling from a browser
The API is meant for server-to-server use. Browser requests are only allowed from Butlr's own origins, so a request from your own web page fails the browser's CORS check. Call the API from your backend instead.
Support
Every response includes an X-Request-ID header. Include it when you contact support about a specific request.
Last updated