Webhooks

Response submitted

Fires when a real (non-test) participant completes a project. Requires Premium tier or above to subscribe. session_number distinguishes repeated completions when max_completes_per_user > 1. user_id + platform_id identify the respondent; call GET /responses?user_id={user_id}&session_number={session_number} after receiving this event to retrieve the full answer set for the exact submission.

postWebhookresponse.submitted

Payload

eventstring
community_idstring
project_idstring
response_idstring nullable

Id of this submission. Pass to GET /communities/{communityId}/projects/{projectId}/responses/{responseId} for the full answer set. Always sent, including on anonymous projects — it is the only join key that survives there.

session_numberinteger nullable

Increments when max_completes_per_user > 1; 1 for first session. null on anonymous projects (it counts one person's repeat completions).

user_idstring nullable

Globally-unique Subo user id. Pass to GET /responses?user_id=&session_number= to retrieve the full answer set for this exact submission. null on anonymous projects.

platform_idstring nullable

The respondent's account id within their platform namespace (the Discord snowflake for a Discord-native community). Unique only when paired with provider. null on anonymous projects.

provider'discord' | 'web'

The account namespace platform_id belongs to. Pair the two to identify the account, or use user_id for an unambiguous lookup. Sent on anonymous projects too — the source a respondent arrived through is not treated as identifying.

completed_atstring date-time

Example payload

{
  "event": "response.submitted",
  "community_id": "1152727606572093543",
  "project_id": "789",
  "response_id": "48120",
  "session_number": 1,
  "user_id": "44821",
  "platform_id": "308994132968210433",
  "provider": "discord",
  "completed_at": "2026-04-30T12:00:00+00:00"
}

Response

Webhook processed successfully

Changes

Webhooks have no change history: a webhook is keyed by its event name rather than a path and method, so no recorded change can name it.