Nice Forms API, OpenAPI, webhooks and CLI
Create surveys, publish them, and pull answers from your own apps with a workspace API key — or import the OpenAPI spec into an agent.
The public Nice Forms API is for the same work you do in the dashboard: surveys, publishing, and responses. Create a key under Account → API, then send it as a Bearer token. Machine-readable contract: GET /openapi.json (YAML at /openapi.yaml).
Nice Forms OpenAPI specification
The full OpenAPI 3.1 document is published at /openapi.json and /openapi.yaml, with aliases at /api/v1/openapi.json and /api/openapi.yaml. Every operation has a unique operationId, a description, typed parameters, and response schemas so LLM function-calling importers can load the Nice Forms API without scraping HTML.
Nice Forms authentication
Every request except GET /api/v1 needs an Authorization header. Keys are shown once when you create them. Revoke a key at any time from the dashboard.
Authorization: Bearer nf_live_…
What you can call
/api/v1API catalog (no key required)
/openapi.jsonOpenAPI 3.1 JSON (no key required)
/openapi.yamlOpenAPI 3.1 YAML (no key required)
/api/v1/meWorkspace and key metadata
/api/v1/surveysList surveys (?status=draft|published|closed)
/api/v1/surveysCreate a survey with title, questions, theme
/api/v1/surveys/:idGet one survey
/api/v1/surveys/:idUpdate survey fields or questions
/api/v1/surveys/:idDelete a survey and its responses
/api/v1/surveys/:id/publishSet status to published
/api/v1/surveys/:id/closeStop accepting responses
/api/v1/surveys/:id/duplicateCopy as a new draft
/api/v1/surveys/:id/responsesList responses (cursor pagination)
/api/v1/surveys/:id/responsesSubmit a response from your app
/api/v1/surveys/:id/responses/:responseIdGet one response
/api/v1/surveys/:id/resultsAggregated counts, views, drop-offs, completions
/api/v1/webhooksList webhook subscriptions
/api/v1/webhooksSubscribe a Zapier, n8n, Slack, Teams, or CRM URL
/api/v1/webhooks/:idUnsubscribe a webhook
/api/v1/openapi.jsonOpenAPI document alias (no key required)
Quick start
curl https://your-domain/api/v1/surveys \
-H "Authorization: Bearer nf_live_…" \
-H "Content-Type: application/json" \
-d '{
"title": "Launch feedback",
"questions": [
{
"type": "multiple_choice",
"title": "Would you use this again?",
"options": [{ "label": "Yes" }, { "label": "Not yet" }]
}
]
}'Pagination
List responses with ?limit=50 (max 100). If pagination.hasMore is true, pass pagination.nextCursor as ?cursor= on the next request. Zapier and n8n can also poll with ?since=2026-01-01T00:00:00.000Z.
Errors
Failed calls return JSON { error, code, message, hint } with HTTP 400, 401, 403, 404, 405, or 429. 401 means the key is missing or invalid — send Authorization: Bearer nf_live_… after creating a key under Account → API. Unknown /api/v1 paths also return that JSON body, never an HTML error page.
Nice Forms CLI
The official Nice Forms CLI wraps the HTTP API for scripts and agents. Install with `npm install -g https://www.nice-forms.com/cli.tgz` or run `npx --package=https://www.nice-forms.com/cli.tgz nice-forms`. The tarball is served from /cli.tgz (script: /cli.mjs). Docs: /developers/cli. Set NICE_FORMS_API_KEY to a workspace key (nf_live_…).
Limits
API keys are workspace-scoped. Basic workspaces still cap free responses at 50 per survey. Pro question types, custom logos, and hidden branding follow your plan, same as the builder.
Zapier, n8n, Slack, Teams, CRM
Do not wait on a native HubSpot or Slack app. Add a webhook under Account → Integrations. We POST when a response is completed. Zapier Catch Hooks, n8n Webhook nodes, Slack/Teams incoming webhooks, and most CRM inbound URLs all accept that POST. For two-way work (create a survey from an app, list answers), use an API key against /api/v1. OpenAPI lives at /api/v1/openapi.json.
Events: response.created, survey.published, survey.closed. JSON payloads include question titles and readable answer text. Slack and Teams formats send a short channel message instead. Deliveries are signed with Nice-Forms-Signature (Stripe-style t=,v1= HMAC). A 410 response disables the endpoint, which is what Zapier REST Hooks expect when a Zap is turned off.
Zapier: Trigger = Webhooks by Zapier → Catch Hook. Action = your CRM, Sheets, or Slack. Optional polling: GET /api/v1/surveys/:id/responses?since=ISO.
n8n: Webhook node (POST) as the start, then HubSpot / Salesforce / HTTP Request. Import GET /openapi.json if you want the REST methods pre-filled.