HTTP 429 rate‑limit failure on GET /v1/designs
0 reputation · 03 Jan 2022, 10:20 UTC
0 reputation · 03 Jan 2022, 10:20 UTC
When pulling a large set of designs from Canva Connect, the integration must traverse the full collection reliably. The current workflow uses the continuation query parameter to page through results, but the API can return HTTP 429 if the rate‑limit is exceeded. This error is not fatal; it requires back‑off and retry logic.
Canva’s documentation does not state that paginated results represent a stable snapshot. If designs are created, edited, or deleted between calls, the same design may appear on multiple pages or be omitted entirely. Additionally, the lifetime and scope of the opaque continuation token are unspecified—whether it can be stored and reused across sessions or if it expires after a short period.
GET /v1/designs calls, or is duplicate and gap risk inherent?continuation token, and can it be safely persisted for later use?35275 reputation · 03 Jan 2022, 15:48 UTC
Assuming the current Canva Connect API version, the service does not document a stable snapshot for GET /v1/designs pagination, so duplicate or missing designs are possible if the collection changes between requests. The continuation token is opaque and its lifetime is unspecified; treat it as short-lived and scoped to the current pagination session. When you receive HTTP 429, honor any Retry-After header if present, otherwise use exponential backoff with jitter. During traversal, collect design IDs in a local set to deduplicate results, and do not persist continuation tokens for later reuse.
| Confirmed | Undocumented / uncertain |
|---|---|
HTTP 429 means the request rate exceeded the allowed limit for the app or token. |
Whether paginated results form a consistent snapshot across calls. |
Pagination uses an opaque continuation query parameter returned in each response. |
The valid duration of a continuation token and whether it can be stored across sessions. |
A 429 response may include Retry-After. |
Whether Retry-After is always present or reliable for this endpoint. |
Keep the loop simple: retry only the failed page request, not the entire traversal. If the response carries Retry-After, wait that many seconds. If not, wait min(base * 2^attempt + jitter, max_delay). Always pass the continuation token from the last successful response. Accumulate design IDs in a set so that if the same design appears on two pages you keep only one copy.
# Inspect 429 headers (safe, read-only)
curl -i -H "Authorization: Bearer $CANVA_TOKEN" \
"https://api.canva.com/rest/v1/designs?limit=50"
In application code, wrap the page fetch in a bounded retry helper:
async function fetchPage(url, token, attempt = 0) {
const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` }});
if (res.status === 429) {
const retryAfter = res.headers.get("Retry-After");
const delay = retryAfter
? parseInt(retryAfter, 10) * 1000
: Math.min(1000 * 2 ** attempt + Math.random() * 500, 30000);
await new Promise(r => setTimeout(r, delay));
return fetchPage(url, token, attempt + 1);
}
if (!res.ok) throw new Error(`Unexpected ${res.status}`);
return res.json();
}
429 to confirm whether Retry-After is present and record its value.429 appears, then confirm your backoff stays under it.continuation token after a short delay (for example, five minutes) and note whether the API accepts it or returns an error; do not rely on persistence until this is verified in your environment.If your 429 responses include a Retry-After header, a fixed wait equal to that value is sufficient and simpler than exponential backoff. If the header is absent, exponential backoff with jitter is required. Do your current 429 responses include Retry-After?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.