{"openapi":"3.1.0","paths":{"/v1/cfti/{surveyId}/respondent/{respondent}":{"get":{"operationId":"get-v1-cfti-{surveyId}-respondent-{respondent}","summary":"Get respondent statistics","description":"Fetch a respondent's interaction history with a survey (when they last responded, viewed, or dismissed it). Useful for deciding whether to show the survey again. Requires the team's publishable key.","tags":["Respondents"],"parameters":[{"in":"path","name":"surveyId","required":true,"schema":{"$ref":"#/components/schemas/surveyIdSchema"},"example":"123"},{"in":"path","name":"respondent","required":true,"schema":{"type":"string"},"example":"example"}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/publicGetRespondentOutputSchema"}}}}}}},"/v1/cfti/{surveyId}/respondent/{respondent}/event":{"post":{"operationId":"post-v1-cfti-{surveyId}-respondent-{respondent}-event","summary":"Record a respondent event","description":"Record that a respondent viewed or dismissed the survey. Requires the team's publishable key.","tags":["Respondents"],"parameters":[{"in":"path","name":"surveyId","required":true,"schema":{"$ref":"#/components/schemas/surveyIdSchema"},"example":"123"},{"in":"path","name":"respondent","required":true,"schema":{"type":"string"},"example":"example"}],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/publicPostRespondentEventInputSchema"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}},"401":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}},"/v1/cfti/{surveyId}/response/{responseId}":{"put":{"operationId":"put-v1-cfti-{surveyId}-response-{responseId}","summary":"Submit a survey response","description":"Create or update a respondent's answers for a survey. The response ID is client-generated, making this idempotent. Requires the team's publishable key.","tags":["Responses"],"parameters":[{"in":"path","name":"surveyId","required":true,"schema":{"$ref":"#/components/schemas/surveyIdSchema"},"example":"123"},{"in":"path","name":"responseId","required":true,"schema":{"anyOf":[{"type":"string","format":"cuid2"},{"type":"string","format":"uuid"}]},"example":"123"}],"security":[{"ApiKeyAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/publicPutResponseInputSchema"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/publicPutResponseOutputSchema"}}}}}}},"/v1/protected/surveys/{surveyId}/responses":{"get":{"operationId":"get-v1-protected-surveys-{surveyId}-responses","summary":"List survey responses","description":"Read a survey's responses for the team the secret key belongs to. Server-to-server only — authenticate with a secret key sent as `Authorization: Bearer cfti_sk_...`. Results are newest-first and paginated: pass the previous page's `nextCursor` as `cursor` to fetch the next page. `limit` defaults to 50 (max 100).","tags":["Responses"],"parameters":[{"in":"query","name":"respondent","required":false,"schema":{"type":"string"}},{"in":"query","name":"cursor","required":false,"schema":{"type":"string"}},{"in":"query","name":"limit","required":false,"schema":{"type":"number"}},{"in":"path","name":"surveyId","required":true,"schema":{"$ref":"#/components/schemas/surveyIdSchema"},"example":"123"}],"security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/protectedListResponsesOutputSchema"}}}}}}},"/v1/cfti/{surveyId}":{"get":{"operationId":"get-v1-cfti-{surveyId}","summary":"Get a survey","description":"Fetch a published survey's questions and configuration by ID. Requires the team's publishable key.","tags":["Surveys"],"parameters":[{"in":"path","name":"surveyId","required":true,"schema":{"$ref":"#/components/schemas/surveyIdSchema"},"example":"123"}],"security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/publicGetSurveyOutputSchema"}}}}}}}},"tags":[{"name":"Respondents","description":"Track and query respondent interactions."},{"name":"Responses","description":"Submit and read survey responses."},{"name":"Surveys","description":"Fetch published surveys."}],"servers":[{"url":"https://confetti.gov.sg/api","description":"Production"}],"components":{"schemas":{"alwaysConditionSchema":{"type":"object","properties":{"type":{"type":"string","enum":["always"]},"target":{"$ref":"#/components/schemas/conditionTargetSchema"}},"required":["type","target"]},"binaryOperatorConditionSchema":{"type":"object","properties":{"type":{"type":"string","enum":["binary-operator"]},"operator":{"type":"string","enum":["equal","not-equal","greater","greater-or-equal","less","less-or-equal","contains","not-contains"]},"value":{"$ref":"#/components/schemas/valueNode"},"target":{"$ref":"#/components/schemas/conditionTargetSchema"}},"required":["type","operator","value","target"]},"bugReportAnswerSchema":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"screenshotDataUrl":{"$ref":"#/components/schemas/imageDataUrlSchema"},"recordingEventsJson":{"$ref":"#/components/schemas/recordingEventsJsonSchema"},"metadata":{"$ref":"#/components/schemas/bugReportMetadataSchema"}},"required":["title","metadata"]},"bugReportDbAnswerSchema":{"type":"string","format":"cuid2"},"bugReportMetadataSchema":{"type":"string"},"bugReportQuestionPropertiesSchema":{"type":"object","properties":{"type":{"type":"string","enum":["bug-report"]},"placeholder":{"type":"string"},"buttonLabel":{"$ref":"#/components/schemas/buttonLabelSchema"},"enableScreenshot":{"type":"boolean"},"enableRecording":{"type":"boolean"},"detailsLabel":{"type":"string"},"detailsPlaceholder":{"type":"string"},"redactClasses":{"type":"array","items":{"type":"string"}}},"required":["type","buttonLabel","enableScreenshot","enableRecording","detailsLabel"]},"buttonLabelSchema":{"type":"string"},"conditionTargetSchema":{"type":"object","discriminator":{"propertyName":"type"},"oneOf":[{"$ref":"#/components/schemas/nextTargetSchema"},{"$ref":"#/components/schemas/jumpTargetSchema"},{"$ref":"#/components/schemas/endTargetSchema"}]},"editableSchema":{"anyOf":[{"type":"object","properties":{"label":{"type":"string"},"max":{"type":"number"},"description":{"type":"string"}},"required":["label","max"]},{"type":"null"}]},"endTargetSchema":{"type":"object","properties":{"type":{"type":"string","enum":["end"]}},"required":["type"]},"eventWithTimeArraySchema":{"type":"array","items":{"$ref":"#/components/schemas/eventWithTimeSchema"}},"eventWithTimeSchema":{"type":"string"},"imageDataUrlSchema":{"type":"string"},"internalMetadataSchema":{"type":"string"},"jumpTargetSchema":{"type":"object","properties":{"type":{"type":"string","enum":["jump"]},"target":{"type":"number"}},"required":["type","target"]},"multiSelectQuestionPropertiesSchema":{"type":"object","properties":{"type":{"type":"string","enum":["multi-select"]},"buttonLabel":{"$ref":"#/components/schemas/buttonLabelSchema"},"options":{"type":"array","items":{"$ref":"#/components/schemas/optionSchema"}},"editable":{"$ref":"#/components/schemas/editableSchema"},"max":{"type":"number"},"display":{"type":"string"}},"required":["type","buttonLabel","options","editable"]},"nextTargetSchema":{"type":"object","properties":{"type":{"type":"string","enum":["next"]}},"required":["type"]},"optionSchema":{"type":"object","properties":{"value":{"type":"string"},"description":{"type":"string"}},"required":["value"]},"protectedListResponsesOutputSchema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/protectedResponseSchema"}},"nextCursor":{"anyOf":[{"type":"string"},{"type":"null"}]},"limit":{"type":"number"},"links":{"type":"object","properties":{"self":{"type":"string"},"next":{"anyOf":[{"type":"string"},{"type":"null"}]}},"required":["self","next"]}},"required":["data","nextCursor","limit","links"]},"protectedListResponsesParamsSchema":{"type":"object","properties":{"surveyId":{"$ref":"#/components/schemas/surveyIdSchema"}},"required":["surveyId"]},"protectedListResponsesQuerySchema":{"type":"object","properties":{"respondent":{"type":"string"},"cursor":{"type":"string"},"limit":{"type":"number"}}},"protectedResponseSchema":{"type":"object","properties":{"id":{"type":"string"},"respondent":{"type":"string"},"data":{"$ref":"#/components/schemas/responseDataSchema"},"clientMetadata":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"}},"required":["id","respondent","data","clientMetadata","createdAt"]},"publicGetRespondentOutputSchema":{"type":"object","properties":{"lastRespondedAt":{"anyOf":[{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date-time"}]},{"type":"null"}]},"lastViewedAt":{"anyOf":[{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date-time"}]},{"type":"null"}]},"lastDismissedAt":{"anyOf":[{"anyOf":[{"type":"string","format":"date-time"},{"type":"string","format":"date-time"}]},{"type":"null"}]}},"required":["lastRespondedAt","lastViewedAt","lastDismissedAt"]},"publicGetRespondentStatisticsParamsSchema":{"type":"object","properties":{"surveyId":{"$ref":"#/components/schemas/surveyIdSchema"},"respondent":{"type":"string"}},"required":["surveyId","respondent"]},"publicGetSurveyOutputSchema":{"type":"object","properties":{"title":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"position":{"type":"number"},"required":{"type":"boolean"},"properties":{"$ref":"#/components/schemas/questionPropertiesSchema"},"routingLogic":{"$ref":"#/components/schemas/routingLogicSchema"}},"required":["id","title","description","position","required","properties","routingLogic"]}},"confirmation":{"$ref":"#/components/schemas/surveyConfirmationSchema"}},"required":["title","description","questions","confirmation"]},"publicGetSurveyParamsSchema":{"type":"object","properties":{"surveyId":{"$ref":"#/components/schemas/surveyIdSchema"}},"required":["surveyId"]},"publicPostRespondentEventInputSchema":{"type":"object","properties":{"type":{"type":"string","enum":["view","dismiss"]}},"required":["type"]},"publicPostRespondentEventParamsSchema":{"type":"object","properties":{"surveyId":{"$ref":"#/components/schemas/surveyIdSchema"},"respondent":{"type":"string"}},"required":["surveyId","respondent"]},"publicPutResponseInputSchema":{"type":"object","properties":{"respondent":{"type":"string"},"data":{"$ref":"#/components/schemas/responseDataSchema"},"metadata":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"telemetry":{"$ref":"#/components/schemas/internalMetadataSchema"}},"required":["respondent","data","metadata"]},"publicPutResponseOutputSchema":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","createdAt"]},"publicPutResponseParamSchema":{"type":"object","properties":{"surveyId":{"$ref":"#/components/schemas/surveyIdSchema"},"responseId":{"anyOf":[{"type":"string","format":"cuid2"},{"type":"string","format":"uuid"}]}},"required":["surveyId","responseId"]},"questionPropertiesSchema":{"type":"object","discriminator":{"propertyName":"type"},"oneOf":[{"$ref":"#/components/schemas/ratingQuestionPropertiesSchema"},{"$ref":"#/components/schemas/singleSelectQuestionPropertiesSchema"},{"$ref":"#/components/schemas/textQuestionPropertiesSchema"},{"$ref":"#/components/schemas/multiSelectQuestionPropertiesSchema"},{"$ref":"#/components/schemas/statementQuestionPropertiesSchema"},{"$ref":"#/components/schemas/bugReportQuestionPropertiesSchema"}]},"ratingQuestionPropertiesSchema":{"type":"object","properties":{"type":{"type":"string","enum":["rating"]},"buttonLabel":{"$ref":"#/components/schemas/buttonLabelSchema"},"shouldAutoProgress":{"$ref":"#/components/schemas/shouldAutoProgressSchema"},"scale":{"type":"number"},"labels":{"type":"object","properties":{"lower":{"type":"string"},"upper":{"type":"string"}}},"display":{"type":"string"}},"required":["type","buttonLabel","shouldAutoProgress","scale"]},"recordingEventsJsonArraySchema":{"type":"array","items":{"$ref":"#/components/schemas/eventWithTimeSchema"}},"recordingEventsJsonSchema":{"type":"string"},"responseDataSchema":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"array","items":{"type":"string"}},{"$ref":"#/components/schemas/bugReportAnswerSchema"}]},"propertyNames":{"type":"string"}},"routingLogicSchema":{"type":"object","discriminator":{"propertyName":"type"},"oneOf":[{"$ref":"#/components/schemas/alwaysConditionSchema"},{"$ref":"#/components/schemas/switchConditionSchema"}]},"shouldAutoProgressSchema":{"type":"boolean"},"singleSelectQuestionPropertiesSchema":{"type":"object","properties":{"type":{"type":"string","enum":["single-select"]},"shouldAutoProgress":{"$ref":"#/components/schemas/shouldAutoProgressSchema"},"options":{"type":"array","items":{"$ref":"#/components/schemas/optionSchema"}},"buttonLabel":{"$ref":"#/components/schemas/buttonLabelSchema"},"editable":{"$ref":"#/components/schemas/editableSchema"}},"required":["type","shouldAutoProgress","options","buttonLabel","editable"]},"statementQuestionPropertiesSchema":{"type":"object","properties":{"type":{"type":"string","enum":["statement"]},"buttonLabel":{"$ref":"#/components/schemas/buttonLabelSchema"},"buttonUrl":{"$ref":"#/components/schemas/urlSchema"}},"required":["type","buttonLabel"]},"surveyConfirmationSchema":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"buttonText":{"type":"string"}},"required":["title","description","buttonText"]},"surveyIdSchema":{"type":"string","format":"cuid2"},"switchConditionSchema":{"type":"object","properties":{"type":{"type":"string","enum":["switch"]},"cases":{"type":"array","items":{"$ref":"#/components/schemas/binaryOperatorConditionSchema"}},"default":{"$ref":"#/components/schemas/conditionTargetSchema"}},"required":["type","cases","default"]},"textQuestionPropertiesSchema":{"type":"object","properties":{"type":{"type":"string","enum":["open-ended"]},"placeholder":{"type":"string"},"buttonLabel":{"$ref":"#/components/schemas/buttonLabelSchema"},"max":{"type":"number"}},"required":["type","buttonLabel","max"]},"urlSchema":{"type":"string"},"valueNode":{"type":"object","properties":{"type":{"type":"string","enum":["value"]},"value":{"anyOf":[{"type":"string"},{"type":"number"}]}},"required":["type","value"]}},"responses":{},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-cfti-pk","description":"Your team's publishable key, found on the Setup page in Confetti."},"BearerAuth":{"type":"http","scheme":"bearer","description":"Your team's secret key (`cfti_sk_...`), sent as a bearer token. Keep it server-side — never expose it in client code."}}},"info":{"title":"Confetti Public API","version":"1.0.0","description":"REST API for integrating with Confetti. The public endpoints are used by the survey widget (`@opengovsg/confetti`) to fetch surveys, submit responses, and record respondent events, authenticated with your team's publishable key (`x-cfti-pk` header). Server-to-server endpoints under `/v1/protected` read data using your team's secret key, sent as a bearer token."},"security":[{"ApiKeyAuth":[]}]}