Poll for results
Understanding how to work with Gamma’s asynchronous API and poll for results
Gamma generation is asynchronous. You start a generation, receive a generationId immediately, then poll the status endpoint until the result is ready.
Looking for general Gamma help? This page covers API polling patterns for developers. For a general overview of the Gamma API, see Does Gamma have an API? in the Help Center.
Quick reference
POST /v1.0/generationsreturnsgenerationIdonly.Poll
GET /v1.0/generations/{generationId}every 5 seconds untilstatusiscompletedorfailed.gammaUrlandexportUrlare only available from the completed status response.Export URLs expire after approximately one week. Anyone with the URL can download the file; access is not tied to your API key. Treat export links as secrets — do not log them, share them, or embed them in client-side code.
Export format matches
exportAs:pdfandpptxdownload directly;pngreturns a.zipwith one PNG per card.
The basic flow
POST /generations → Returns { generationId: "abc123" }
Wait ~5 seconds
GET /generations/abc123 → Returns { status: "pending" }
Wait ~5 seconds
GET /generations/abc123 → Returns { status: "completed", gammaUrl: "...", exportUrl: "..." }What you get back
When status is completed, the response includes:
gammaUrl
Direct link to view/share the presentation in Gamma
exportUrl
Download URL for the exported file (if exportAs was specified). png exports are a .zip with one PNG per card. Expires after about one week; treat the URL as a secret.
Generation states
pending
Still generating
Keep polling every 5 seconds
completed
Done!
Stop polling — use gammaUrl and export URLs
failed
Something went wrong
Stop polling, check the error object
Code examples
Using automation platforms
Popular automation platforms have built-in ways to handle delays and polling:
Zapier
Use the Delay action between your HTTP Request steps:
HTTP Request (POST) → Start generation, get
generationIdDelay for → Wait 30-60 seconds
HTTP Request (GET) → Check status with the
generationIdUse Paths or Filter to check if
statusequalscompletedIf still pending, use Looping by Zapier to repeat steps 2-4
Zapier's "Delay for" action pauses your Zap for a specified time (minimum 1 minute). For most Gamma generations, a single 60-second delay followed by a status check works well.
Make (formerly Integromat)
Use the Sleep module or a polling pattern:
HTTP module → POST to start generation
Sleep module → Wait 30 seconds
HTTP module → GET to check status
Router with filter → Check if
statusiscompletedUse Repeater + Sleep for polling loop
n8n
Use the Wait node with time interval:
HTTP Request node → POST to start generation
Wait node → Set to "After Time Interval" (30-60 seconds)
HTTP Request node → GET to check status
IF node → Check
status === "completed"Loop back to Wait node if still pending
n8n's Wait node offloads execution data to the database during longer waits, so your workflow won't timeout even for complex generations.
Best practices
Use 5-second polling intervals. Polling more frequently will not speed up the generation and may increase the chance of rate limiting.
Set a maximum timeout. Most generations complete within 2-3 minutes, so a 5-minute ceiling is a good default for automation.
Handle all three states:
pending,completed, andfailed.Use exponential backoff if you receive a 429 response.
Running multiple generations
You can start multiple generations in parallel. To manage throughput:
Use the
x-ratelimit-remaining-burstheader on each response to pace your requests. See Rate limit headers and adaptive polling below for how to read these headers.Stagger your
POST /generationscalls and poll the resulting IDs round-robin rather than waiting for each generation to complete before starting the next.If responses slow down or you receive a
429, back off and let the rate limit headers guide your pacing.
Starting a generation without waiting
POST /generations returns a generationId immediately — you do not need to wait for the generation to finish inline. To poll later, all you need is your API key and the generationId.
This is useful for workflows that start a generation in one step and check the result in a later step. For example, a multi-step automation can fire off a generation, continue with other work, and come back to poll GET /generations/{generationId} when it is ready to use the result.
Monitoring credit usage
The credits field (with deducted and remaining) appears on completed and failed poll responses. It is not included while the generation is still pending.
Check
credits.remainingafter each completed generation before starting another.If credits run out, subsequent
POST /generationscalls return402with"Insufficient credits remaining". Checking the remaining balance proactively avoids unexpected failures mid-workflow.Enable auto-recharge to avoid interruptions.
Rate limit headers and adaptive polling
Every API response includes headers that show your current rate limit usage. Use these to adjust your polling speed dynamically instead of waiting for a 429 error.
To see these headers in curl, add the -i flag. You can also use -v for full verbose output including request headers and TLS details, but -i is cleaner for inspecting rate limits.
Without -i, you'd only see the JSON body. The headers are always present — -i just tells curl to display them. In Python, JavaScript, or any HTTP client, these headers are always accessible on the response object without any special flag.
x-ratelimit-limit-burst
Maximum requests allowed in the current short window
x-ratelimit-remaining-burst
Requests remaining in the current short window
x-ratelimit-limit
Maximum requests allowed per hour
x-ratelimit-remaining
Requests remaining in the current hour
x-ratelimit-limit-daily
Maximum requests allowed per day
x-ratelimit-remaining-daily
Requests remaining today
Adaptive polling example
Instead of a fixed 5-second interval, read x-ratelimit-remaining-burst and slow down when capacity is low:
Generation time varies. Larger decks, AI-generated images, and higher-quality image models all increase generation time. A 5-card deck with no images may complete in under a minute, while a 40-card deck with AI images could take several minutes. Factor this into your timeout and polling logic — there is no single "right" interval for all requests.
Handling a 429 response
If you hit the rate limit, the API returns 429 Too Many Requests. Pause for 30 seconds before retrying, then use exponential backoff if subsequent requests also return 429.
Common issues
status stays pending for too long
Generations typically complete in 1-3 minutes. If you are waiting longer than 5 minutes:
Check that you're polling the correct
generationIdVerify your API key has sufficient credits
Try generating with fewer cards (
numCards) to test
You receive a 429 rate-limit response
If you receive a 429 error:
Use 5+ second polling intervals
Use
curl -ito check thex-ratelimit-remaining-burstheader and see if you're near the limitSee Rate limit headers and adaptive polling above for how to throttle dynamically
If you're using Zapier, Make, or n8n, the rate limit may be on the platform side rather than Gamma's
Related
Error codes for the full list of API errors and troubleshooting guidance
Generate from text for parameter-level guidance on
POST /v1.0/generationsCharts and structured content for prompting charts and infographics
Image URL best practices for including your own images
API Overview for a broader workflow comparison
Last updated
Was this helpful?