openapi: 3.0.3 info: title: Delighted API description: >- REST API for the Delighted customer satisfaction platform. Enables sending surveys, retrieving and adding survey responses, accessing NPS and CSAT metrics, managing Autopilot drip campaigns, handling webhooks for real-time events, and managing people records including unsubscribes and bounces. Authentication is via HTTP Basic Auth using per-project API keys. version: v1 contact: name: Delighted Support url: https://app.delighted.com/docs/api termsOfService: https://delighted.com/terms license: name: Proprietary url: https://delighted.com/terms servers: - url: https://api.delighted.com/v1 description: Delighted API v1 security: - basicAuth: [] tags: - name: People description: Manage people records for survey targeting - name: Survey Responses description: Create and retrieve survey responses - name: Metrics description: Retrieve NPS and satisfaction metrics - name: Unsubscribes description: Manage unsubscribe lists - name: Bounces description: Retrieve bounced email records - name: Autopilot description: Manage Autopilot drip campaign configuration and membership paths: /people.json: post: operationId: sendToPersonOrCreatePerson summary: Send survey to person description: >- Creates or updates a person record and optionally schedules a survey to be sent to them. If the person already exists (matched by email or phone), their record is updated with any new properties. tags: - People requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/SendToPersonRequest' responses: '200': description: Person created or updated successfully content: application/json: schema: $ref: '#/components/schemas/PersonSurveyResponse' '401': description: Unauthorized - invalid or missing API key '429': description: Rate limit exceeded headers: Retry-After: schema: type: integer description: Seconds to wait before retrying get: operationId: listPeople summary: List people description: Returns a paginated list of people in the project. tags: - People parameters: - name: per_page in: query description: Number of results per page. Default is 20, maximum is 100. schema: type: integer default: 20 maximum: 100 - name: since in: query description: Unix timestamp to limit results to people created on or after this time. schema: type: integer - name: until in: query description: Unix timestamp to limit results to people created on or before this time. schema: type: integer - name: email in: query description: Restricts results to a specific person by email address. schema: type: string format: email - name: phone_number in: query description: Phone number in E.164 format (e.g. +17132746524). schema: type: string responses: '200': description: List of people headers: Link: schema: type: string description: Cursor-based pagination link for next page content: application/json: schema: type: array items: $ref: '#/components/schemas/Person' '401': description: Unauthorized '429': description: Rate limit exceeded /people/{person_identifier}: delete: operationId: deletePerson summary: Delete person description: >- Deletes the specified person and all information related to them, including surveys, responses, properties, Autopilot membership, survey history, integration links, unsubscribe/bounce status, and testimonials. tags: - People parameters: - name: person_identifier in: path required: true description: >- Person identifier. Can be the person ID (e.g. 24248363), email prefixed with 'email:' (e.g. email:jony@appleseed.com), or phone number prefixed with 'phone_number:' (e.g. phone_number:+17132746524). schema: type: string responses: '202': description: Person deletion accepted content: application/json: schema: $ref: '#/components/schemas/OkResponse' '401': description: Unauthorized '404': description: Person not found '429': description: Rate limit exceeded /people/{person_email}/survey_requests/pending.json: delete: operationId: deletePendingSurveyRequests summary: Delete pending survey requests description: >- Removes all scheduled (not yet sent) survey requests for the specified person. tags: - People parameters: - name: person_email in: path required: true description: Email of the person whose pending surveys should be deleted. schema: type: string format: email responses: '200': description: Pending surveys deleted successfully content: application/json: schema: $ref: '#/components/schemas/OkResponse' '401': description: Unauthorized '404': description: Person not found '429': description: Rate limit exceeded /survey_responses.json: get: operationId: listSurveyResponses summary: List survey responses description: Returns a paginated list of survey responses for the project. tags: - Survey Responses parameters: - name: per_page in: query description: Results per page. Default is 20, maximum is 100. schema: type: integer default: 20 maximum: 100 - name: page in: query description: Page number to retrieve. Default is 1. schema: type: integer default: 1 - name: since in: query description: Unix timestamp filtering responses created on or after this time. schema: type: integer - name: until in: query description: Unix timestamp filtering responses created on or before this time. schema: type: integer - name: updated_since in: query description: Unix timestamp filtering responses updated on or after this time. schema: type: integer - name: updated_until in: query description: Unix timestamp filtering responses updated on or before this time. schema: type: integer - name: trend in: query description: Trend ID to restrict responses to a specific trend. schema: type: string - name: person_id in: query description: Person ID to filter responses for a specific individual. schema: type: string - name: person_email in: query description: Email address to filter responses for a specific person. schema: type: string format: email - name: order in: query description: >- Sort order. One of: asc (chronological), desc (reverse), asc:updated_at, or desc:updated_at. schema: type: string enum: - asc - desc - asc:updated_at - desc:updated_at - name: expand[] in: query description: Objects to expand in response. Can be 'person' and/or 'notes'. schema: type: array items: type: string enum: - person - notes style: form explode: true responses: '200': description: List of survey responses content: application/json: schema: type: array items: $ref: '#/components/schemas/SurveyResponse' '401': description: Unauthorized '429': description: Rate limit exceeded post: operationId: addSurveyResponse summary: Add survey response description: Manually adds a survey response for an existing person. tags: - Survey Responses requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AddSurveyResponseRequest' responses: '200': description: Survey response created content: application/json: schema: $ref: '#/components/schemas/SurveyResponse' '401': description: Unauthorized '422': description: Unprocessable entity - validation error '429': description: Rate limit exceeded /metrics.json: get: operationId: getMetrics summary: Get metrics description: >- Returns NPS and satisfaction metrics for the project. By default returns core metrics; optionally returns metrics grouped by delivery channel. tags: - Metrics parameters: - name: since in: query description: Unix timestamp to restrict metrics to those created on or after this time. schema: type: integer - name: until in: query description: Unix timestamp to restrict metrics to those created on or before this time. schema: type: integer - name: trend in: query description: Restricts metrics to a specific trend using its ID. schema: type: string - name: groups[] in: query description: >- Metric groups to return. Options: core, email, kiosk, link, sms, web. Default is core. schema: type: array items: type: string enum: - core - email - kiosk - link - sms - web style: form explode: true responses: '200': description: Project metrics content: application/json: schema: $ref: '#/components/schemas/Metrics' '401': description: Unauthorized '429': description: Rate limit exceeded /unsubscribes.json: post: operationId: unsubscribePerson summary: Unsubscribe person description: >- Adds a person to the unsubscribe list, preventing them from receiving further survey emails. Does not remove their previous survey responses. tags: - Unsubscribes requestBody: required: true content: application/json: schema: type: object required: - person_email properties: person_email: type: string format: email description: Email of the person to unsubscribe. responses: '200': description: Person unsubscribed successfully content: application/json: schema: $ref: '#/components/schemas/OkResponse' '401': description: Unauthorized '404': description: Person not found '429': description: Rate limit exceeded get: operationId: listUnsubscribedPeople summary: List unsubscribed people description: Returns a paginated list of people who have unsubscribed from surveys. tags: - Unsubscribes parameters: - name: per_page in: query description: Number of results per page. Default is 20, maximum is 100. schema: type: integer default: 20 maximum: 100 - name: page in: query description: Page number to return. Default is 1. schema: type: integer default: 1 - name: since in: query description: Unix timestamp to filter unsubscribes on or after this date. schema: type: integer - name: until in: query description: Unix timestamp to filter unsubscribes on or before this date. schema: type: integer responses: '200': description: List of unsubscribed people content: application/json: schema: type: array items: $ref: '#/components/schemas/UnsubscribedPerson' '401': description: Unauthorized '429': description: Rate limit exceeded /bounces.json: get: operationId: listBouncedPeople summary: List bounced people description: >- Returns a paginated list of people whose survey emails have bounced. Results are returned oldest first. tags: - Bounces parameters: - name: per_page in: query description: Number of results per page. Default is 20, maximum is 100. schema: type: integer default: 20 maximum: 100 - name: page in: query description: Page number to return. Default is 1. schema: type: integer default: 1 - name: since in: query description: Unix timestamp to filter bounces on or after this time. schema: type: integer - name: until in: query description: Unix timestamp to filter bounces on or before this time. schema: type: integer responses: '200': description: List of bounced people content: application/json: schema: type: array items: $ref: '#/components/schemas/BouncedPerson' '401': description: Unauthorized '429': description: Rate limit exceeded /autopilot/email.json: get: operationId: getAutopilotEmailConfiguration summary: Get Autopilot email configuration description: Returns the Autopilot configuration for the email channel. tags: - Autopilot responses: '200': description: Autopilot email configuration content: application/json: schema: $ref: '#/components/schemas/AutopilotConfiguration' '401': description: Unauthorized '429': description: Rate limit exceeded /autopilot/sms.json: get: operationId: getAutopilotSmsConfiguration summary: Get Autopilot SMS configuration description: Returns the Autopilot configuration for the SMS channel. tags: - Autopilot responses: '200': description: Autopilot SMS configuration content: application/json: schema: $ref: '#/components/schemas/AutopilotConfiguration' '401': description: Unauthorized '429': description: Rate limit exceeded /autopilot/email/memberships.json: get: operationId: listAutopilotEmailMembers summary: List people in email Autopilot description: Returns a paginated list of people enrolled in the email Autopilot campaign. tags: - Autopilot parameters: - name: per_page in: query description: Results per page. Default is 20, maximum is 100. schema: type: integer default: 20 maximum: 100 - name: person_id in: query description: Filter by person ID. schema: type: string - name: person_email in: query description: Filter by person email. schema: type: string format: email - name: person_phone_number in: query description: Filter by phone number in E.164 format. schema: type: string responses: '200': description: List of Autopilot email memberships headers: Link: schema: type: string description: Cursor-based pagination link for next page content: application/json: schema: type: array items: $ref: '#/components/schemas/AutopilotMembership' '401': description: Unauthorized '429': description: Rate limit exceeded post: operationId: addPersonToAutopilotEmail summary: Add person to email Autopilot description: Enrolls a person in the email Autopilot drip campaign. tags: - Autopilot requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AutopilotMembershipRequest' responses: '200': description: Person added to Autopilot content: application/json: schema: $ref: '#/components/schemas/AutopilotMembershipCreated' '401': description: Unauthorized '422': description: Unprocessable entity '429': description: Rate limit exceeded delete: operationId: removePersonFromAutopilotEmail summary: Remove person from email Autopilot description: >- Removes a person from the email Autopilot campaign and cancels any already-scheduled Autopilot surveys. Preserves the person record and existing responses. tags: - Autopilot requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AutopilotRemoveRequest' responses: '200': description: Person removed from Autopilot content: application/json: schema: $ref: '#/components/schemas/AutopilotRemoveResponse' '401': description: Unauthorized '404': description: Person not found in Autopilot '429': description: Rate limit exceeded /autopilot/sms/memberships.json: get: operationId: listAutopilotSmsMembers summary: List people in SMS Autopilot description: Returns a paginated list of people enrolled in the SMS Autopilot campaign. tags: - Autopilot parameters: - name: per_page in: query description: Results per page. Default is 20, maximum is 100. schema: type: integer default: 20 maximum: 100 - name: person_id in: query description: Filter by person ID. schema: type: string - name: person_email in: query description: Filter by person email. schema: type: string format: email - name: person_phone_number in: query description: Filter by phone number in E.164 format. schema: type: string responses: '200': description: List of Autopilot SMS memberships headers: Link: schema: type: string description: Cursor-based pagination link for next page content: application/json: schema: type: array items: $ref: '#/components/schemas/AutopilotMembership' '401': description: Unauthorized '429': description: Rate limit exceeded post: operationId: addPersonToAutopilotSms summary: Add person to SMS Autopilot description: Enrolls a person in the SMS Autopilot drip campaign. tags: - Autopilot requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AutopilotMembershipRequest' responses: '200': description: Person added to SMS Autopilot content: application/json: schema: $ref: '#/components/schemas/AutopilotMembershipCreated' '401': description: Unauthorized '422': description: Unprocessable entity '429': description: Rate limit exceeded delete: operationId: removePersonFromAutopilotSms summary: Remove person from SMS Autopilot description: >- Removes a person from the SMS Autopilot campaign and cancels any already-scheduled Autopilot surveys. tags: - Autopilot requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AutopilotRemoveRequest' responses: '200': description: Person removed from Autopilot content: application/json: schema: $ref: '#/components/schemas/AutopilotRemoveResponse' '401': description: Unauthorized '404': description: Person not found in Autopilot '429': description: Rate limit exceeded components: securitySchemes: basicAuth: type: http scheme: basic description: >- Use your Delighted API key as the username. Leave the password empty. The API key is found in your project settings. schemas: SendToPersonRequest: type: object description: Request body for sending a survey to a person. properties: email: type: string format: email description: >- Email of the person. Required if phone_number is not provided or channel is email. phone_number: type: string description: >- Contact number in E.164 format. Required if channel is sms. channel: type: string enum: - email - sms description: Survey delivery method. Defaults to email. name: type: string description: Person's name. delay: type: integer description: Seconds to wait before sending the survey. Default is 0. properties: type: object additionalProperties: type: string description: >- Custom metadata fields for segmentation and integration. Supports special keys: question_product_name, delighted_email_subject, delighted_intro_message, locale, thank_you_message, thank_you_link_text, thank_you_link_url. send: type: boolean description: Set false to create person without sending a survey. Default is true. default: true last_sent_at: type: integer description: >- Unix timestamp for survey throttling consideration. Used when syncing historical send data. email_update: type: string format: email description: New email address when updating an existing contact. phone_number_update: type: string description: New phone number when updating an existing contact. PersonSurveyResponse: type: object description: Response after sending survey to or creating a person. properties: id: type: string description: Unique person identifier. email: type: string format: email description: Person's email address. name: type: string nullable: true description: Person's name. survey_scheduled_at: type: integer description: Unix timestamp when the survey is scheduled to be sent. properties: type: object additionalProperties: type: string description: Custom properties associated with the person. Person: type: object description: A person record in the Delighted project. properties: id: type: string description: Unique person identifier. email: type: string format: email description: Person's email address. name: type: string nullable: true description: Person's name. created_at: type: integer description: Unix timestamp when the person was created. phone_number: type: string nullable: true description: Person's phone number in E.164 format. last_sent_at: type: integer nullable: true description: Unix timestamp when the last survey was sent. last_responded_at: type: integer nullable: true description: Unix timestamp when the person last responded to a survey. next_survey_scheduled_at: type: integer nullable: true description: Unix timestamp when the next survey is scheduled to be sent. SurveyResponse: type: object description: A survey response record. properties: id: type: string description: Unique response identifier. person: type: string description: Person ID associated with this response. survey_type: type: string description: Type of survey (e.g. nps, csat, ces). score: type: integer description: Survey score given by the respondent. comment: type: string nullable: true description: Optional comment provided by the respondent. permalink: type: string format: uri description: Shareable URL to the survey response. created_at: type: integer description: Unix timestamp when the response was created. updated_at: type: integer description: Unix timestamp when the response was last updated. person_properties: type: object additionalProperties: type: string description: Custom properties associated with the person at time of response. notes: type: array items: $ref: '#/components/schemas/Note' description: Notes attached to this response. tags: type: array items: type: string description: Tags applied to this response. additional_answers: type: array items: $ref: '#/components/schemas/AdditionalAnswer' description: Responses to additional survey questions. Note: type: object description: A note attached to a survey response. properties: id: type: string description: Note identifier. text: type: string description: Note content. user_email: type: string format: email description: Email of the team member who added the note. created_at: type: integer description: Unix timestamp when the note was created. AdditionalAnswer: type: object description: Response to an additional survey question. properties: question: type: object properties: id: type: string description: Question identifier. type: type: string enum: - free_response - scale - select_one - select_many description: Question type. text: type: string description: Question text. answer: description: Answer value; type varies based on question type. oneOf: - type: string - type: integer - type: array items: type: string AddSurveyResponseRequest: type: object required: - person - score description: Request body for manually adding a survey response. properties: person: type: string description: The ID of the person providing the response. score: type: integer minimum: 0 maximum: 10 description: Rating from 0-10. comment: type: string description: Optional feedback text from the respondent. person_properties: type: object additionalProperties: type: string description: Custom key-value pairs to attach to the response. created_at: type: integer description: >- Unix timestamp when the response was collected. Defaults to current time if omitted. Metrics: type: object description: NPS and satisfaction metrics for the project. properties: nps: type: integer description: Net Promoter Score. promoter_count: type: integer description: Number of promoter responses. promoter_percent: type: integer description: Percentage of promoters. passive_count: type: integer description: Number of passive responses. passive_percent: type: integer description: Percentage of passives. detractor_count: type: integer description: Number of detractor responses. detractor_percent: type: integer description: Percentage of detractors. response_count: type: integer description: Total number of responses. UnsubscribedPerson: type: object description: A person who has unsubscribed from surveys. properties: person_id: type: string description: Unique identifier for the person. email: type: string format: email description: Email address of the unsubscribed person. name: type: string nullable: true description: Name of the person. unsubscribed_at: type: integer description: Unix timestamp when the unsubscription occurred. BouncedPerson: type: object description: A person whose survey email has bounced. properties: person_id: type: string description: Unique identifier for the person. email: type: string format: email description: Email address of the bounced contact. name: type: string nullable: true description: Person's name. bounced_at: type: integer description: Unix timestamp when the bounce occurred. AutopilotConfiguration: type: object description: Autopilot configuration for a delivery channel. properties: platform_id: type: string description: The name of the distribution platform (e.g. email, sms). active: type: boolean description: Whether Autopilot is enabled for this platform. frequency: type: integer description: Number of seconds between recurring surveys for people in Autopilot. created_at: type: integer description: Unix timestamp when this configuration was initially set up. updated_at: type: integer description: Unix timestamp of the most recent configuration change. AutopilotMembershipRequest: type: object description: Request body for adding a person to Autopilot. properties: person_id: type: string description: Person's unique identifier. person_email: type: string format: email description: Person's email address. Required for email Autopilot. person_phone_number: type: string description: Person's phone number in E.164 format. Required for SMS Autopilot. person_name: type: string description: Person's name. properties: type: object additionalProperties: type: string description: >- Custom key-value pairs for segmentation. Supports special keys: question_product_name, delighted_email_subject, delighted_intro_message, locale, thank_you_message, thank_you_link_text, thank_you_link_url. AutopilotMembershipCreated: type: object description: Response after adding a person to Autopilot. properties: person: $ref: '#/components/schemas/Person' properties: type: object additionalProperties: type: string description: Custom properties set for this Autopilot membership. AutopilotMembership: type: object description: An Autopilot membership record. properties: created_at: type: integer description: Unix timestamp when the person joined Autopilot. updated_at: type: integer description: Unix timestamp of last property or survey change. person: type: object properties: id: type: string name: type: string nullable: true email: type: string format: email phone_number: type: string nullable: true created_at: type: integer next_survey_request: type: object nullable: true properties: id: type: string description: Survey request identifier. created_at: type: integer description: Unix timestamp when the survey request was created. survey_scheduled_at: type: integer description: Unix timestamp when the survey is scheduled to be sent. properties: type: object additionalProperties: type: string description: Custom property key-value pairs. AutopilotRemoveRequest: type: object description: >- Request body for removing a person from Autopilot. Specify exactly one identifier. properties: person_id: type: string description: Unique identifier of the person. person_email: type: string format: email description: Email address of the person. person_phone_number: type: string description: Phone number in E.164 format. AutopilotRemoveResponse: type: object description: Response after removing a person from Autopilot. properties: person: type: object properties: id: type: string name: type: string nullable: true email: type: string format: email created_at: type: integer phone_number: type: string nullable: true OkResponse: type: object description: Simple success response. properties: ok: type: boolean description: Indicates the operation was successful. example: true WebhookPayload: type: object description: >- Webhook payload sent by Delighted for survey_response.created, survey_response.updated, and unsubscribe.created events. properties: event_type: type: string enum: - survey_response.created - survey_response.updated - unsubscribe.created description: The type of event that triggered the webhook. event_id: type: string description: Unique identifier for the event, used for deduplication across retries. event_data: type: object description: Event-specific data payload.