For Google Forms — API Reference

Versioned machine API for creating Google Forms from plain text. Base URL: https://for-google-forms.surveysai.com/api/v1/forgoogleforms Machine-readable spec: /api/v1/forgoogleforms/openapi.json

Quickstart

# 1. Log in with Google at https://for-google-forms.surveysai.com/ and create
#    an API key in the dashboard (API keys section). Keys look like fgf_...

# 2. Parse / check a form (free):
curl -X POST https://for-google-forms.surveysai.com/api/v1/forgoogleforms/parse \
  -H "Authorization: Bearer fgf_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"form_text": "Customer Feedback\n*Full Name [text]\nRating [linear_scale]"}'

# 3. Create the real Google Form (billed, 10 API credits independently of PRO):
curl -X POST https://for-google-forms.surveysai.com/api/v1/forgoogleforms/forms \
  -H "Authorization: Bearer fgf_YOUR_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f2b8c1e-7a4d-4f6b-9e21-5c0d8a9b7e64" \
  -d '{"form_text": "Customer Feedback\n*Full Name [text]"}'

Authentication

Authorization: Bearer fgf_... — see auth guide. Scopes: forms:read, forms:write, validate, credits:read.

Endpoints

Method Path Auth / scope Billed
GET /capabilities public —
GET /pricing public —
GET /openapi.json public —
POST /parse validate free
POST /validate validate free; use_llm: true → 2 credits
GET /forms forms:read free
POST /forms forms:write 10 credits
GET /me any key free
GET /credits/ledger credits:read free
POST /credits/checkout any key — (payment)

All request bodies are JSON. Form input is the plain-text format described in QUESTION_TYPES.md (summary at /llms.txt).

POST /forms

Body: {"form_text": "..."}. Optional header Idempotency-Key: <string> (max 255 characters, surrounding whitespace is ignored; use a random value such as a UUID). The key is scoped to the API key owner's account and to the action — it never matches another account's request. Repeating a successful call with the same key returns the original result without creating or charging again. Responses:

  • 201 — {status, data: {form_id, google_form_id, form_url, question_count, warnings, charged_credits}}
  • 200 — replay of a previous successful idempotent call (data.replayed: true)
  • 400 — missing_form_text, or invalid_idempotency_key (longer than 255 characters)
  • 401 — invalid_api_key
  • 402 — insufficient credits; body contains x402-style accepts array with top-up instructions (see payments guide)
  • 403 — insufficient_scope (key lacks forms:write) or action_not_allowed (the key's action whitelist excludes form creation)
  • 409 — one of:
    • google_account_not_linked, google_token_unreadable or google_token_refresh_rejected: the key's owner must log in once more via the web so the service can store a valid Google refresh token;
    • google_scope_missing: the owner signed in but did not allow Google Forms access on Google's consent screen; they must log in via the web again and keep "See, edit, create and delete all your Google Forms forms" checked (no credit is charged);
    • credit_reconciliation_required: the credit account requires manual refund/reconciliation resolution;
    • idempotency_key_conflict: an earlier call with the same key is still in progress or did not succeed (it was refunded). Retry with a new Idempotency-Key.
  • 413 — form_text_too_large (over 100 kB)
  • 422 — parse_failed (details in errors) or no_questions (the message explains the plain-text format with an example, typically the text was sent as YAML, JSON or Markdown); fix and retry
  • 429 — rate limit exceeded, or daily_budget_exceeded (key's daily credit budget)
  • 500 — create_persistence_failed: the Google Form was created but could not be saved; the credit is refunded
  • 502 — google_forms_error or google_token_refresh_failed: an upstream Google call failed; the credit is refunded
  • 503 — api_disabled (operator kill-switch)

POST /validate with use_llm: true

Billed (2 credits). The same account-scoped Idempotency-Key prevents a double charge on retry, but LLM results are not stored: repeating a key returns 409 idempotency_key_conflict instead of a free re-run. Use a new key for each validation.

Errors

Errors returned by the API: {"status": "error", "error": "<code>", "message": "..."} with appropriate HTTP status (schema Error in the OpenAPI spec; 402 extends it as PaymentRequired). 503 api_disabled means the operator kill-switch is on. Exceptions: a rate-limit 429 and an unexpected 500 may have a non-JSON body, so check the HTTP status first. Every operation lists its full set of status codes in the OpenAPI spec; a test in CI keeps the spec in sync with the code.

POST /credits/checkout

Body: {"credits": 200..20000, "currency": "usd"|"eur"}. One credit costs 0.01 in the selected currency. Purchased credits do not expire and do not require PRO.

Rate limits

Default 120 requests/hour per API key (creation endpoints lower). Per-action credit budgets can be set per key (daily_credit_limit).

Versioning and deprecation

  • The major version is part of the path (/api/v1/). Within v1, changes are additive only: new operations, new optional request fields, new response fields and new error codes. Clients should ignore unknown fields.
  • operationId values are stable identifiers and are not renamed within v1.
  • A breaking change ships as /api/v2/ alongside v1. v1 then stays available for at least 6 months, the deprecation is announced in this document and in info.description of the OpenAPI spec, and deprecated operations are marked deprecated: true.
  • info.version in the spec follows semantic versioning of the contract.

Early Feedback Welcome!

If you try this tool and have suggestions, we'd love to hear from you. Your input helps shape the future of AI-powered form creation.

Share Your Feedback