Clipform

OAuth for apps

Authorize an app to act on a user's Clipform workspace.

OAuth is for apps other people install - the Clipform apps for Zapier and Make use it. Your users click Connect, sign in to Clipform, pick a workspace, and approve; you never handle their password and they can revoke you at any time.

Building a private integration for your own workspace? Use an API key instead - it is simpler and does the same job.

Client credentials are issued per app. Email support@clipform.io with your app name and redirect URI to get a client_id and client_secret.

Endpoints

PurposeEndpoint
Authorizationhttps://api.clipform.io/oauth/authorize
Token + refreshhttps://api.clipform.io/oauth/token
Revocation (RFC 7009)https://api.clipform.io/oauth/revoke

These are separate from the MCP server at mcp.clipform.io, whose tokens are audience-bound to MCP. Tokens issued here carry no audience restriction and authorize the REST API at api.clipform.io.

Scopes

ScopeGrants
forms:readRead the workspace's forms
responses:readRead the workspace's form responses
webhooks:manageSubscribe and unsubscribe webhook endpoints

Request only what you use. Scopes are space-separated in the scope parameter.

The flow

1. Send the user to authorize

https://api.clipform.io/oauth/authorize
  ?client_id=your_client_id
  &redirect_uri=https://your-app.example/callback
  &response_type=code
  &scope=forms:read%20responses:read%20webhooks:manage
  &state=random_value

Public clients (no secret) must also send code_challenge and code_challenge_method=S256 (PKCE). Clipform redirects back with ?code=...&state=....

2. Exchange the code for tokens

curl -X POST https://api.clipform.io/oauth/token \
  -d grant_type=authorization_code \
  -d code=the_code \
  -d redirect_uri=https://your-app.example/callback \
  -d client_id=your_client_id \
  -d client_secret=your_client_secret
{
  "access_token": "cf_at_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "cf_rt_...",
  "scope": "forms:read responses:read webhooks:manage",
  "workspace_name": "Acme Marketing"
}

3. Call the API

curl -H "Authorization: Bearer cf_at_your_token" \
  https://api.clipform.io/v1/connect/me

Get the connected workspace is the quickest way to confirm a connection works - it returns the workspace_id and workspace_name the token is bound to, which makes a good connection label.

Refreshing

Access tokens last 1 hour; refresh tokens last 90 days and rotate on every use, so store the new one each time.

curl -X POST https://api.clipform.io/oauth/token \
  -d grant_type=refresh_token \
  -d refresh_token=cf_rt_your_token \
  -d client_id=your_client_id \
  -d client_secret=your_client_secret

Refresh before the access token expires. An expired access token is rejected as an ordinary 401, not as a distinct "token expired" signal, so a platform that only refreshes reactively will see hard failures.

Reusing an already-rotated refresh token is treated as a possible theft (RFC 9700) and revokes the whole token family, forcing the user to reconnect.

Errors

Token endpoint errors follow RFC 6749:

{ "error": "invalid_grant", "error_description": "Invalid or expired refresh token" }

The REST API uses Clipform's own shape:

{ "code": "UNAUTHORIZED", "error": "Invalid or expired token" }

What you can call

The Integrations endpoints are the connect lane an installed app uses: identify the workspace, list its forms, and subscribe to form completions. Deliveries follow the standard webhook payload.

Users manage and revoke your app's access from Settings → Connected apps in their dashboard.