For the complete documentation index, see llms.txt. This page is also available as Markdown.

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/generations returns generationId only.

  • Poll GET /v1.0/generations/{generationId} every 5 seconds until status is completed or failed.

  • gammaUrl and exportUrl are 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: pdf and pptx download directly; png returns a .zip with 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:

Field
Description

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

Status
Meaning
What to Do

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:

  1. HTTP Request (POST) → Start generation, get generationId

  2. Delay for → Wait 30-60 seconds

  3. HTTP Request (GET) → Check status with the generationId

  4. Use Paths or Filter to check if status equals completed

  5. If 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:

  1. HTTP module → POST to start generation

  2. Sleep module → Wait 30 seconds

  3. HTTP module → GET to check status

  4. Router with filter → Check if status is completed

  5. Use Repeater + Sleep for polling loop

n8n

Use the Wait node with time interval:

  1. HTTP Request node → POST to start generation

  2. Wait node → Set to "After Time Interval" (30-60 seconds)

  3. HTTP Request node → GET to check status

  4. IF node → Check status === "completed"

  5. 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, and failed.

  • 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-burst header on each response to pace your requests. See Rate limit headers and adaptive polling below for how to read these headers.

  • Stagger your POST /generations calls 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.remaining after each completed generation before starting another.

  • If credits run out, subsequent POST /generations calls return 402 with "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.

Header
Description

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 generationId

  • Verify 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 -i to check the x-ratelimit-remaining-burst header and see if you're near the limit

  • See 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

Last updated

Was this helpful?