Skip to content

Getting Started with the API

The SurveyRock API is a REST API served from https://app.surveyrock.com/api/v1. All requests and responses use JSON.

API tokens are created from your workspace settings in the SurveyRock app (Settings → API Tokens). Each token is scoped to a specific set of permissions and belongs to a live or test environment — see Authentication for the full model.

API access requires a paid plan. Free-tier workspaces cannot generate tokens.

Every request needs an Authorization header carrying your token as a bearer credential:

Terminal window
curl https://app.surveyrock.com/api/v1/surveys \
-H "Authorization: Bearer srk_live_..."

A successful response looks like this:

{
"success": true,
"data": [
{ "id": "mlb8i9f2UZLhXwJA", "name": "Q3 NPS", "status": "published" }
],
"meta": { "timestamp": "2026-07-23T12:00:00Z", "requestId": "..." }
}

Every endpoint follows the same envelope shape: success, data, and meta. Error responses replace data with a structured error object — see Errors.

The full API Reference is generated directly from the API’s live OpenAPI schema, so it always reflects exactly what’s deployed — endpoints, parameters, and response shapes never drift out of sync with this guide.

The API currently covers surveys, elements, questions, responses, drafts/versions, distribution (web links, QR codes, embeds), contacts, response exports, and events: signed webhooks and an event feed (see Webhooks and Events). Breadth is actively expanding — check the API Reference for the current, authoritative endpoint list rather than assuming this guide’s examples are exhaustive.

  • Requests are rate-limited per plan tier — see Rate Limits.
  • Non-GET requests should include an Idempotency-Key header so retries never double-apply a write. Endpoints that require it will reject a request without one. Creating a webhook and rotating its secret are the exceptions, because their responses carry a secret we don’t store: see Idempotency and retries.
  • Updates to a survey, an element (rating and NPS questions included), a distributor or a contact require an If-Match header, so two writers cannot overwrite each other. Reading one of these returns its current ETag, both as the ETag response header and as meta.etag in the JSON body: send that value back as If-Match. A missing header is a 428; a stale one is a 412 and nothing is written, so re-read the resource, reapply your change to what is there now, and retry. A successful write returns the next ETag. See the API Reference for which endpoints require it.