openapi: 3.1.0 info: title: Loops OpenAPI Spec description: This is the OpenAPI Spec for the [Loops API](https://loops.so/docs/api). version: 1.8.0 servers: - url: https://app.loops.so/api/v1 tags: - name: API key - name: Contacts description: Manage contacts in your audience - name: Contact properties description: Manage contact properties - name: Mailing lists description: View mailing lists - name: Events description: Trigger email sending with events - name: Transactional emails description: Send and view transactional emails - name: Dedicated sending IPs description: View dedicated sending IP addresses paths: /api-key: get: tags: - API key summary: Test your API key responses: "200": description: Success content: application/json: schema: type: object properties: success: type: boolean examples: - true teamName: type: string description: The name of the team the API key belongs to. examples: - "Company name" required: - success - teamName "401": description: Invalid API key content: application/json: schema: type: object properties: success: type: boolean examples: - false message: type: string examples: - Invalid API key error: type: string examples: - Invalid API key security: - apiKey: [] /contacts/create: post: tags: - Contacts summary: Create a contact description: Add a contact to your audience. requestBody: description: You can add custom contact properties as keys in this request (of type `string`, `number`, `boolean` or `date` ([see available date formats](https://loops.so/docs/contacts/properties#dates))).
Make sure to create the properties in Loops before using them in API calls. content: application/json: schema: $ref: "#/components/schemas/ContactRequest" required: true responses: "200": description: Successful create. content: application/json: schema: $ref: "#/components/schemas/ContactSuccessResponse" "400": description: Bad request (e.g. invalid email address). content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" "405": description: Wrong HTTP request method. "409": description: Email or `userId` already exists. content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" security: - apiKey: [] /contacts/update: put: tags: - Contacts summary: Update a contact description: Update a contact by `email` or `userId`. You must provide one of these parameters.
If you want to update a contact’s email address, the contact will first need a `userId` value. You can then make a request containing the userId field along with an updated email address. requestBody: description: You can add custom contact properties as keys in this request (of type `string`, `number`, `boolean` or `date` ([see available date formats](https://loops.so/docs/contacts/properties#dates))).
Make sure to create the properties in Loops before using them in API calls. content: application/json: schema: $ref: "#/components/schemas/ContactUpdateRequest" required: true responses: "200": description: Successful update. content: application/json: schema: $ref: "#/components/schemas/ContactSuccessResponse" "400": description: Bad request (e.g. `email` or `userId` are missing). content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" "405": description: Wrong HTTP request method. security: - apiKey: [] /contacts/find: get: tags: - Contacts summary: Find a contact description: Search for a contact by `email` or `userId`. Only one parameter is allowed. parameters: - name: email in: query required: false description: Email address (URI-encoded) schema: type: string - name: userId in: query required: false schema: type: string responses: "200": description: List of contacts (or an empty array if no contact was found). Contact objects will include any custom properties. content: application/json: schema: type: array items: $ref: "#/components/schemas/Contact" "400": description: Bad request (e.g. invalid email address). content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" "405": description: Wrong HTTP request method. security: - apiKey: [] /contacts/delete: post: tags: - Contacts summary: Delete a contact description: Delete a contact by `email` or `userId`. requestBody: description: Include only one of `email` or `userId`. content: application/json: schema: $ref: "#/components/schemas/ContactDeleteRequest" required: true responses: "200": description: Successful delete. content: application/json: schema: $ref: "#/components/schemas/ContactDeleteResponse" "400": description: Bad request (e.g. `email` and `userId` are both provided). content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" "404": description: Contact not found. content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" "405": description: Wrong HTTP request method. security: - apiKey: [] /contacts/suppression: get: tags: - Contacts summary: Get suppression status for a contact description: Retrieve suppression status and removal quota for a contact by `email` or `userId`. Include only one query parameter. parameters: - name: email in: query required: false description: Email address (URI-encoded) schema: type: string - name: userId in: query required: false schema: type: string responses: "200": description: Successful. content: application/json: schema: $ref: "#/components/schemas/ContactSuppressionStatusResponse" "400": description: Bad request (e.g. invalid email address). content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" "404": description: Contact not found. content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" "405": description: Wrong HTTP request method. security: - apiKey: [] delete: tags: - Contacts summary: Remove a contact from suppression list description: Remove a suppressed contact from the suppression list by `email` or `userId`. Include only one query parameter. parameters: - name: email in: query required: false description: Email address (URI-encoded) schema: type: string - name: userId in: query required: false schema: type: string responses: "200": description: Successful removal. content: application/json: schema: $ref: "#/components/schemas/ContactSuppressionRemoveResponse" "400": description: Bad request (e.g. contact is not suppressed). content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" "404": description: Contact not found. content: application/json: schema: $ref: "#/components/schemas/ContactFailureResponse" "405": description: Wrong HTTP request method. security: - apiKey: [] /contacts/properties: post: tags: - Contact properties summary: Create a contact property description: Add a contact property to your team. requestBody: description: The name value must be in camelCase, like `planName`. content: application/json: schema: $ref: "#/components/schemas/ContactPropertyCreateRequest" required: true responses: "200": description: Successful create. content: application/json: schema: $ref: "#/components/schemas/ContactPropertySuccessResponse" "400": description: Bad request (e.g. invalid type). content: application/json: schema: $ref: "#/components/schemas/ContactPropertyFailureResponse" "405": description: Wrong HTTP request method. security: - apiKey: [] get: tags: - Contact properties summary: Get a list of contact properties description: Retrieve a list of your account's contact properties.
Use the `list` parameter to query "all" or "custom" properties. parameters: - name: list in: query required: false description: \"all\" (default) or \"custom\" schema: type: string responses: "200": description: Successful. content: application/json: schema: type: array items: $ref: "#/components/schemas/ContactProperty" "405": description: Wrong HTTP request method. security: - apiKey: [] /dedicated-sending-ips: get: tags: - Dedicated sending IPs summary: Get dedicated sending IP addresses description: Retrieve a list of Loops' dedicated sending IP addresses. responses: "200": description: Successful. content: application/json: schema: type: array description: List of dedicated sending IP addresses items: type: string description: IP address examples: - "1.2.3.4" "405": description: Wrong HTTP request method. "500": description: Internal server error. content: application/json: schema: type: object properties: success: type: boolean message: type: string required: - success - message security: - apiKey: [] /lists: get: tags: - Mailing lists summary: Get a list of mailing lists description: Retrieve a list of your account's mailing lists. responses: "200": description: Successful. content: application/json: schema: type: array items: $ref: "#/components/schemas/MailingList" "405": description: Wrong HTTP request method. security: - apiKey: [] /events/send: post: tags: - Events summary: Send an event description: Send events to trigger emails in Loops. requestBody: description: Provide either `email` or `userId` to identify the contact ([read more](https://loops.so/docs/api-reference/send-event#body)).
You can add event properties, which will be available in emails sent by this event. Values can be of type string, number, boolean or date ([see allowed date formats](https://loops.so/docs/events/properties#important-information-about-event-properties)).
Make sure to create the properties in Loops before using them in API calls.
You can add contact properties as keys in this request (of type `string`, `number`, `boolean` or `date` ([see available date formats](https://loops.so/docs/contacts/properties#dates))). content: application/json: schema: $ref: "#/components/schemas/EventRequest" required: true parameters: - in: header name: Idempotency-Key description: Include a unique ID for this request (maximum 100 characters) to avoid duplicate events. [More info](https://loops.so/docs/api-reference/send-event#param-idempotency-key) schema: type: string maxLength: 100 responses: "200": description: Successful send. content: application/json: schema: $ref: "#/components/schemas/EventSuccessResponse" "400": description: Bad request (e.g. `eventName` is missing). content: application/json: schema: $ref: "#/components/schemas/EventFailureResponse" "405": description: Wrong HTTP request method. "409": description: Idempotency key has been used. content: application/json: schema: $ref: "#/components/schemas/IdempotencyKeyFailureResponse" security: - apiKey: [] /transactional: post: tags: - Transactional emails summary: Send a transactional email description: Send a transactional email to a contact.
Please [email us](mailto:help@loops.so) to enable attachments on your account before using them with the API. requestBody: content: application/json: schema: $ref: "#/components/schemas/TransactionalRequest" required: true parameters: - in: header name: Idempotency-Key description: Include a unique ID for this request (maximum 100 characters) to avoid duplicate emails. [More info](https://loops.so/docs/api-reference/send-transactional-email#param-idempotency-key) schema: type: string maxLength: 100 responses: "200": description: Successful send. content: application/json: schema: $ref: "#/components/schemas/TransactionalSuccessResponse" "400": description: Bad request (e.g. transactional email is not published). content: application/json: schema: oneOf: - $ref: "#/components/schemas/TransactionalFailureResponse" - $ref: "#/components/schemas/TransactionalFailure2Response" - $ref: "#/components/schemas/TransactionalFailure3Response" - $ref: "#/components/schemas/TransactionalFailure4Response" - $ref: "#/components/schemas/TransactionalFailure5Response" "404": description: Transactional email not found. content: application/json: schema: $ref: "#/components/schemas/TransactionalFailure3Response" "405": description: Wrong HTTP request method. "409": description: Idempotency key has been used. content: application/json: schema: $ref: "#/components/schemas/IdempotencyKeyFailureResponse" security: - apiKey: [] get: tags: - Transactional emails summary: List transactional emails description: Get a list of published transactional emails. parameters: - name: perPage in: query required: false description: How many results to return in each request. Must be between 10 and 50. Default is 20. schema: type: string - name: cursor in: query required: false description: A cursor, to return a specific page of results. Cursors can be found from the `pagination.nextCursor` value in each response. schema: type: string responses: "200": description: Successful. content: application/json: schema: $ref: "#/components/schemas/ListTransactionalsResponse" "405": description: Wrong HTTP request method. security: - apiKey: [] components: schemas: Contact: type: object properties: id: type: string email: type: string firstName: type: - string - "null" lastName: type: - string - "null" source: type: string subscribed: type: boolean userGroup: type: string userId: type: - string - "null" mailingLists: type: object description: An object of mailing list IDs and boolean subscription statuses. examples: - list_123: true optInStatus: type: - string - "null" description: Double opt-in status. enum: [accepted, pending, rejected, null] ContactRequest: type: object required: - email properties: email: type: string firstName: type: string lastName: type: string subscribed: type: boolean userGroup: type: string userId: type: string mailingLists: type: object description: An object of mailing list IDs and boolean subscription statuses. examples: - list_123: true additionalProperties: oneOf: - type: string - type: number - type: boolean ContactUpdateRequest: type: object properties: email: type: string firstName: type: string lastName: type: string subscribed: type: boolean userGroup: type: string userId: type: string mailingLists: type: object description: An object of mailing list IDs and boolean subscription statuses. examples: - list_123: true additionalProperties: oneOf: - type: string - type: number - type: boolean ContactSuccessResponse: type: object properties: success: type: boolean examples: - true id: type: string required: - success - id ContactFailureResponse: type: object properties: success: type: boolean examples: - false message: type: string required: - success - message ContactDeleteRequest: type: object properties: email: type: string userId: type: string required: - email - userId ContactDeleteResponse: type: object properties: success: type: boolean examples: - true message: type: string examples: - Contact deleted. required: - success - message ContactSuppressionStatusResponse: type: object properties: contact: type: object properties: id: type: string email: type: string userId: type: - string - "null" required: - id - email - userId isSuppressed: type: boolean removalQuota: $ref: "#/components/schemas/ContactSuppressionRemovalQuota" required: - contact - isSuppressed - removalQuota ContactSuppressionRemoveResponse: type: object properties: success: type: boolean examples: - true message: type: string examples: - Email removed from suppression list. removalQuota: $ref: "#/components/schemas/ContactSuppressionRemovalQuota" required: - success - message - removalQuota ContactSuppressionRemovalQuota: type: object properties: limit: type: number remaining: type: number required: - limit - remaining ContactPropertyCreateRequest: type: object required: - name - type properties: name: type: string type: type: string ContactPropertySuccessResponse: type: object properties: success: type: boolean examples: - true required: - success ContactPropertyFailureResponse: type: object properties: success: type: boolean examples: - false message: type: string required: - success - message EventRequest: type: object required: - eventName properties: email: type: string userId: type: string eventName: type: string eventProperties: type: object description: An object containing event property data for the event, available in emails sent by the event. mailingLists: type: object description: An object of mailing list IDs and boolean subscription statuses. examples: - list_123: true additionalProperties: oneOf: - type: string - type: number - type: boolean EventSuccessResponse: type: object properties: success: type: boolean examples: - true required: - success EventFailureResponse: type: object properties: success: type: boolean examples: - false message: type: string required: - success - message TransactionalRequest: type: object required: - email - transactionalId properties: email: type: string transactionalId: type: string description: The ID of the transactional email to send. addToAudience: type: boolean description: If `true`, a contact will be created in your audience using the `email` value (if a matching contact doesn't already exist). dataVariables: type: object description: An object containing contact data as defined by the data variables added to the transactional email template. examples: - name: Chris passwordResetLink: https://example.com/reset-password attachments: type: array description: A list containing file objects to be sent along with an email message. items: type: object required: - filename - contentType - data properties: filename: type: string description: The name of the file, shown in email clients. contentType: type: string description: The MIME type of the file. data: type: string description: The base64-encoded content of the file. TransactionalSuccessResponse: type: object properties: success: type: boolean examples: - true required: - success TransactionalFailureResponse: type: object properties: success: type: boolean examples: - false message: type: string required: - success - message TransactionalFailure2Response: type: object properties: success: type: boolean examples: - false message: type: string path: type: string required: - success - message - path TransactionalFailure3Response: type: object properties: success: type: boolean examples: - false message: type: string error: type: object properties: path: type: string message: type: string required: - success - message - error TransactionalFailure4Response: type: object properties: success: type: boolean examples: - false message: type: string error: type: object properties: path: type: string reason: type: string required: - success - message - error TransactionalFailure5Response: type: object properties: success: type: boolean examples: - false message: type: string error: type: object properties: path: type: string message: type: string transactionalId: type: string required: - success - message - error - transactionalId IdempotencyKeyFailureResponse: type: object properties: success: type: boolean examples: - false message: type: string required: - success - message TransactionalEmail: type: object properties: id: type: string name: type: string lastUpdated: type: string dataVariables: type: array examples: - id: cll42l54f20i1la0lfooe3z12 name: Sign up confirmation lastUpdated: "2025-02-02T02:56:28.845Z" dataVariables: ["confirmationUrl"] required: - id - name - lastUpdated - dataVariables ListTransactionalsResponse: type: object properties: pagination: type: object properties: totalResults: type: number returnedResults: type: number perPage: type: number totalPages: type: number nextCursor: type: - string - "null" nextPage: type: - string - "null" data: type: array items: $ref: "#/components/schemas/TransactionalEmail" ContactProperty: type: object properties: key: type: string label: type: string type: type: string examples: - key: favoriteColor label: Favorite color type: string required: - key - label - type MailingList: type: object properties: id: type: string name: type: string description: type: string isPublic: type: boolean examples: - id: list_123 name: Main mailing list description: Mailing list description isPublic: true required: - id - name - description - isPublic securitySchemes: apiKey: type: http scheme: bearer