API keys
Call the QuickPinMaker API from your own tools, scripts and automations.
Your keys
Quick start
Send your key in the Authorization header. A key acts as your account, so anything it does uses your plan and spends your credits. Keep it secret, and revoke it if it leaks.
Try it
You can also send the key as an X-API-Key header.
Permissions
- read Look things up: your pins, reports, boards, credits.
- write Change things that do not publish or cost credits: uploads, saved skills, brand kit.
- publish Create, edit or delete pins, schedule plans, use AI and chat. These publish to Pinterest or spend credits.
Keys cannot manage keys, billing, saved partner secrets or your profile. Those need you signed in.
Your key
New keys look like qpm_live_ followed by 46 letters and digits, the last 6 being a checksum, so secret scanners can spot them. Older keys that start with qpm_ keep working. Send the key only in a header, over HTTPS. Never put it in a web address or query string: requests with ?api_key= or ?key= are refused with status 400, because addresses end up in logs. Call the API from your server, not from a web page, and do not give a key to the browser.
Rate limits
Each key has a limit per minute (a sliding window, so there is no burst at the minute edge), and your account has a limit per day shared by all keys. Every response carries these headers:
RateLimit-Limit,RateLimit-RemainingandRateLimit-Reset(seconds from now) for the minute window, andRateLimit-Policy, for example60;w=60, 20000;w=86400(the minute and the day).X-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Resetare the same numbers for older clients, but the reset is a Unix time in seconds.X-RateLimit-Daily-Limit,X-RateLimit-Daily-RemainingandX-RateLimit-Daily-Reset(a Unix time) for the day, which resets at 00:00 UTC.- Every response also has an
X-Request-Id. Send your own (8 to 64 letters, digits or . _ : ) to trace a call, and quote it to support.
Errors and backoff
Errors are application/problem+json with type, title, status, detail, code (for example rate_limited, daily_limit, insufficient_scope, invalid_api_key), requestId and, on 429, retryAfter in seconds. The plain error field is still there. A 401 has a WWW-Authenticate header, and a 403 for a missing permission names the scope it needs. On a 429 wait for the Retry-After seconds, then try again:
for (let tries = 0; tries < 5; tries++) {
const res = await fetch(url, { headers: { Authorization: "Bearer " + key } });
if (res.status !== 429) return res;
const wait = Number(res.headers.get("Retry-After")) || 2 ** tries;
await new Promise((r) => setTimeout(r, (wait + Math.random()) * 1000));
}Responses to key requests are marked Cache-Control: no-store. Browsers from other sites are not allowed to call the API with a key.