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