# Archive account
Source: https://docs.surge.app/api-reference/endpoint/accounts/archive
DELETE /accounts/{id}
Archives an account and releases all associated resources.
**Warning**: This action will:
- Release all phone numbers associated with the account
- Deactivate all campaigns
- Make the account unusable for sending messages
This operation is irreversible. If you need to send SMS in the future, you will need to re-register new phone numbers and campaigns.
# Check account status
Source: https://docs.surge.app/api-reference/endpoint/accounts/check-status
GET /accounts/{account_id}/status
Check an account's status and capabilities
# Create account
Source: https://docs.surge.app/api-reference/endpoint/accounts/create
POST /accounts
Creates a new Account within the calling Platform.
# List accounts
Source: https://docs.surge.app/api-reference/endpoint/accounts/list
GET /accounts
List all accounts for the calling platform with cursor-based pagination.
# Update account
Source: https://docs.surge.app/api-reference/endpoint/accounts/update
PATCH /accounts/{id}
Updates an Account
# Get file
Source: https://docs.surge.app/api-reference/endpoint/attachments/get_file
GET /attachments/{attachment_id}/file
Redirects to a signed URL where the attachment file can be downloaded. URL is short-lived, so redirect should be followed immediately.
# Add contact
Source: https://docs.surge.app/api-reference/endpoint/audiences/add_contact
POST /audiences/{audience_id}/contacts
Adds an existing contact to a manual audience.
# Create audience
Source: https://docs.surge.app/api-reference/endpoint/audiences/create
POST /accounts/{account_id}/audiences
Creates a new audience.
# List contacts
Source: https://docs.surge.app/api-reference/endpoint/audiences/list_contacts
GET /audiences/{audience_id}/contacts
List all contacts in an audience with cursor-based pagination. The account is inferred from the audience.
# Send blast
Source: https://docs.surge.app/api-reference/endpoint/blasts/create
POST /accounts/{account_id}/blasts
Sends a Blast.
# Create campaign
Source: https://docs.surge.app/api-reference/endpoint/campaigns/create
POST /accounts/{account_id}/campaigns
Creates a campaign to register account to send text messages.
# Get campaign
Source: https://docs.surge.app/api-reference/endpoint/campaigns/get
GET /campaigns/{id}
Retrieves a Campaign object.
# List campaigns
Source: https://docs.surge.app/api-reference/endpoint/campaigns/list
GET /accounts/{account_id}/campaigns
List all campaigns for an account with cursor-based pagination.
# Update campaign
Source: https://docs.surge.app/api-reference/endpoint/campaigns/update
PATCH /campaigns/{id}
Updates a campaign that has not yet been approved. This can be used to fix issues flagged during review and resubmit the campaign. Returns an error if the campaign is currently in review, has already been approved, or has been deactivated.
# Create contact
Source: https://docs.surge.app/api-reference/endpoint/contacts/create
POST /accounts/{account_id}/contacts
Creates a new Contact object.
# Retrieve contact
Source: https://docs.surge.app/api-reference/endpoint/contacts/get
GET /contacts/{id}
Retrieves a Contact object.
# List contacts
Source: https://docs.surge.app/api-reference/endpoint/contacts/list
GET /accounts/{account_id}/contacts
List all contacts for an account with cursor-based pagination.
# Update contact
Source: https://docs.surge.app/api-reference/endpoint/contacts/update
PATCH /contacts/{id}
Updates the specified contact by setting the values of the parameters passed. Any parameters not provided will be left unchanged.
# Create message
Source: https://docs.surge.app/api-reference/endpoint/messages/create
POST /accounts/{account_id}/messages
Creates and enqueues a new message to be sent.
Messages are always sent asynchronously. When you hit this endpoint, the message will be created within Surge's system and enqueued for sending, and then the id for the new message will be returned. When the message is actually sent, a `message.sent` webhook event will be triggered and sent to any webhook endpoints that you have subscribed to this event type. Then a `message.delivered` webhook event will be triggered when the carrier sends us a delivery receipt.
By default all messages will be sent immediately. If you would like to schedule sending for some time up to 60 days in the future, you can do that by providing a value for the `send_at` field. This should be formatted as an ISO8601 datetime like `2028-10-14T18:06:00Z`.
You must include either a `body` or `attachments` field (or both) in the request body. The `body` field should contain the text of the message you want to send, and the `attachments` field should be an array of objects with a `url` field pointing to the file you want to attach. Surge will download these files and send them as attachments in the message.
You can provide either a `conversation` object or a `to` field to specify the intended recipient of the message, but an error will be returned if both fields are provided. Similarly the `from` field cannot be used together with the `conversation` field, and `conversation.phone_number` should be specified instead.
# Retrieve message
Source: https://docs.surge.app/api-reference/endpoint/messages/get
GET /messages/{id}
Retrieves a Message object.
# List messages
Source: https://docs.surge.app/api-reference/endpoint/messages/list
GET /accounts/{account_id}/messages
List all messages for an account with cursor-based pagination.
# List phone numbers
Source: https://docs.surge.app/api-reference/endpoint/phone-numbers/list
GET /accounts/{account_id}/phone_numbers
List all phone numbers for an account with cursor-based pagination.
# Purchase phone number
Source: https://docs.surge.app/api-reference/endpoint/phone-numbers/purchase
POST /accounts/{account_id}/phone_numbers
Purchase a new phone number for the account. You can specify search criteria or let the system select a random number.
# Release phone number
Source: https://docs.surge.app/api-reference/endpoint/phone-numbers/release
DELETE /phone_numbers/{id}
Releases a phone number from the account.
# Delete recording
Source: https://docs.surge.app/api-reference/endpoint/recordings/delete
DELETE /recordings/{id}
Deletes a recording. The recording file will be removed from storage asynchronously.
# Get recording
Source: https://docs.surge.app/api-reference/endpoint/recordings/get
GET /recordings/{id}
Retrieves a Recording object.
# Get file
Source: https://docs.surge.app/api-reference/endpoint/recordings/get_file
GET /recordings/{recording_id}/file
Redirects to a signed URL where the recording audio file can be downloaded. URL is short-lived, so redirect should be followed immediately.
# List recordings
Source: https://docs.surge.app/api-reference/endpoint/recordings/list
GET /accounts/{account_id}/recordings
List all recordings for an account with cursor-based pagination.
# Create user
Source: https://docs.surge.app/api-reference/endpoint/users/create
POST /accounts/{account_id}/users
Creates a new User object.
# Create user token
Source: https://docs.surge.app/api-reference/endpoint/users/create-token
POST /users/{user_id}/tokens
Provides a mechanism for having Surge create a signed token for embeds instead of signing with your own signing key.
# Delete user
Source: https://docs.surge.app/api-reference/endpoint/users/delete
DELETE /users/{id}
Deletes a user.
Once a user has been deleted, they will no longer be permitted to access any
of the embedded components. Attempting to access a deleted user will return
a 404 Not Found error.
# Retrieve user
Source: https://docs.surge.app/api-reference/endpoint/users/get
GET /users/{id}
Retrieves a User object.
# List users
Source: https://docs.surge.app/api-reference/endpoint/users/list
GET /accounts/{account_id}/users
List all users for an account with cursor-based pagination.
# Update user
Source: https://docs.surge.app/api-reference/endpoint/users/update
PATCH /users/{id}
Updates an existing User object.
# Check verification
Source: https://docs.surge.app/api-reference/endpoint/verifications/check
POST /verifications/{id}/checks
Checks the code against a verification.
# Send verification
Source: https://docs.surge.app/api-reference/endpoint/verifications/create
POST /accounts/{account_id}/verifications
Creates a new Verification for an account and sends the code to the given phone number.
# Introduction
Source: https://docs.surge.app/api-reference/introduction
The Surge API allows you to create a tighter integration between your
application and the Surge platform. This will provide a better experience for
your customers and allow you to do more advanced things like automating
workflows.
The API is organized in a RESTful way with predictable HTTP verbs and URLs. We
are constantly updating it to provide more features and improve the overall
experience. If you have any feedback or need help, please reach out to us at
[support@surge.app](mailto:support@surge.app).
# Call Ended
Source: https://docs.surge.app/api-reference/webhooks/call/ended
webhook callEnded
The `call.ended` event is delivered whenever a call is completed between a Surge number you own and another phone number.
# Campaign Approved
Source: https://docs.surge.app/api-reference/webhooks/campaign/approved
webhook campaignApproved
The `campaign.approved` event is delivered whenever a campaign is approved by all of the US carriers and able to start sending text messages.
# Contact Opted In
Source: https://docs.surge.app/api-reference/webhooks/contact/opted_in
webhook contactOptedIn
The `contact.opted_in` event is delivered whenever a contact opts back in to receiving messages by sending a keyword message (START, YES, UNSTOP).
# Contact Opted Out
Source: https://docs.surge.app/api-reference/webhooks/contact/opted_out
webhook contactOptedOut
The `contact.opted_out` event is delivered whenever a contact opts out of receiving messages by sending a keyword message (STOP, CANCEL, UNSUBSCRIBE, etc.).
# Conversation Created
Source: https://docs.surge.app/api-reference/webhooks/conversation/created
webhook conversationCreated
The `conversation.created` event is delivered whenever a new conversation is started with a contact. This could be when either the contact sends a message to your Surge number or when you create a conversation, whether by sending an initial message to the contact or by manually creating the conversation using the API.
# Introduction
Source: https://docs.surge.app/api-reference/webhooks/intro
Webhooks are like having a super-responsive assistant who taps you on the
shoulder whenever something interesting happens in your SMS operations. Instead
of constantly asking "Did I get a message? Did someone click my link?", webhooks
proactively notify your application when these events occur.
## Why use webhooks?
* Real-time updates: receive instant notifications when things happen
* Automation friendly: perfect for building automated workflows
* Efficient: no need to poll for updates, we'll let you know when something happens
* Reliable: make sure you never miss an important event
## Getting started
To start receiving webhooks, you'll need to:
1. Set up a publicly accessible HTTPS endpoint on your server
2. Register your webhook URL in the Surge dashboard
3. Implement handlers for the events you care about
While it's not required to get started, we strongly encourage
[validating webhook signatures](/api-reference/webhooks/signature-validation)
to ensure the events you receive are coming from Surge.
## Webhook delivery & retries
When your server receives a webhook, it's like getting a high-five from our
system - and we want to make sure that high-five connects! Your endpoint should
respond with either a `200 OK` or `201 Created` HTTP status code to let us know
you've successfully received the webhook.
If your server is having a rough day (hey, it happens to the best of us!),
our retry system has got your back: Surge will attempt to deliver the webhook up
to 20 times, using exponential backoff with jitter to make sure we don't
overwhelm your system.
## Best practices
To ensure you're handling Surge's webhooks like a pro:
1. Make your webhook handlers *idempotent* - receiving the same webhook multiple
times should not have any unintended side effects
2. Validate webhook signatures to ensure the events you receive are coming from
Surge.
3. Respond to webhooks quickly - if your server is slow to respond, we may
attempt to deliver the webhook multiple times
And as always, if you have any questions or need help, please reach out to us at
[support@surge.app](mailto:support@surge.app).
# Link Followed
Source: https://docs.surge.app/api-reference/webhooks/link/followed
webhook linkFollowed
The `link.followed` event is delivered when a contact first follows a shortened link that was included in a message sent from a Surge number. This event is only triggered on the first click of each link; subsequent clicks on the same link do not generate additional events.
# Message Delivered
Source: https://docs.surge.app/api-reference/webhooks/message/delivered
webhook messageDelivered
The `message.delivered` event is delivered whenever a message sent from a Surge number is successfully delivered to the recipient. When the message is sent from a short code or toll-free number, this means that the message arrived on the recipient's device. When sent from a local number, this means that the message was successfully handed off to the recipient's mobile carrier, but does not guarantee that it arrived on the recipient's device.
# Message Failed
Source: https://docs.surge.app/api-reference/webhooks/message/failed
webhook messageFailed
The `message.failed` event is delivered whenever a message sent from your Surge number fails to be delivered.
# Message Received
Source: https://docs.surge.app/api-reference/webhooks/message/received
webhook messageReceived
The `message.received` event is delivered whenever a message is received at a Surge number from a contact.
# Message Sent
Source: https://docs.surge.app/api-reference/webhooks/message/sent
webhook messageSent
The `message.sent` event is delivered whenever a message is sent from a Surge number to a contact.
# Phone Number Attached to Campaign
Source: https://docs.surge.app/api-reference/webhooks/phone_number/attached_to_campaign
webhook phoneNumberAttachedToCampaign
The `phone_number.attached_to_campaign` event is delivered whenever a phone number is attached to a campaign.
# Recording Completed
Source: https://docs.surge.app/api-reference/webhooks/recording/completed
webhook recordingCompleted
The `recording.completed` event is delivered whenever a call recording has been processed and is ready for playback. This event is not triggered for voicemail recordings.
# Webhook Signature Validation
Source: https://docs.surge.app/api-reference/webhooks/signature-validation
Signatures provide a method to verify the authenticity and integrity of incoming webhooks. By
using a shared secret and a defined verification process, you can ensure that webhooks are
genuinely from Surge and haven't been modified.
## Surge-Signature header
Each webhook Surge delivers includes a "Surge-Signature" header that looks like this:
```
Surge-Signature: t=1737830031,v1=41f947e88a483327c878d6c08b27b22fbe7c9ea5608b035707c6667d1df866dd
```
Parameters:
* `t`: Unix timestamp indicating when webhook was sent
* `v1`: Lowercase hex-encoded HMAC-SHA256 signature
* We may send more than one `v1` hash when rolling credentials
Parameter names and values will not include `,` or `=`, so these can be split upon to parse the header.
## Validation Steps
1. **Check timestamp**: Verify timestamp is within an acceptable time window (such as 5 minutes) to prevent replay attacks.
2. **Generate payload**: The payload signed to create the header is a concatenation of 3 things:
1. Timestamp from step 1
2. Period (`.`)
3. Raw webhook body
Example
```
1737830031.{"type":"message.received","id":"evt_01jjfeev3hf9n9c7k5231hd3hr",...}
```
3. **Compute expected hash**: Generate HMAC-SHA256 hash for the payload from step 2.
* Use the signing secret you received when setting up your webhook endpoint.
4. **Compare hashes**: Check computed hash from step 3 with `v1` from header.
* Use constant-time string comparison to protect against timing attacks.
* There may be multiple `v1` parameters in the header
* Only compare to `v1`, not other versions which may be added in the future
* If any of the `v1` hashes match, the signature should be accepted as authentic
# Voicemail Received
Source: https://docs.surge.app/api-reference/webhooks/voicemail/received
webhook voicemailReceived
The `voicemail.received` event is delivered whenever a voicemail recording has been processed and is ready for playback.
# Register a campaign
Source: https://docs.surge.app/guides/carrier-registration/register-a-campaign
To crack down on spam and other undesirable messaging, carriers must know the legal entity responsible for each text message sent from software to a device on their network. Each phone number that will be sending messages from an application to a person must be associated with a "campaign" that explains who will be sending messages, why, and how the end user will opt in to and out of receiving them.
This guide covers registering a campaign through the API for an account.
Skip this step if you already have an account for this campaign.
Many fields on the account are optional at this step but will be required to register a campaign. Certain fields will also affect requirements for other fields; `organization.type`, for example, drastically affects which fields are required. We therefore recommend including all the fields you believe you need in the intial create to reduce iterations on providing missing fields.
See "[Create an account](/api-reference/endpoint/accounts/create)".
Here's an example where most of the fields required for local messaging are provided.
```sh title="Request" maxLines="15" theme={null}
curl -X POST https://api.surge.app/accounts \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"name": "DT Precision Auto",
"organization": {
"address": {
"name": "DT Precision Auto",
"line1": "2640 Huron St",
"locality": "Los Angeles",
"postal_code": "90065",
"region": "CA",
"country": "US"
},
"contact": {
"first_name": "Dominic",
"last_name": "Toretto",
"email": "dom@dtprecisionauto.com",
"phone_number": "+13235556439"
},
"industry": "automotive",
"type": "llc",
"website": "https://dtprecisionauto.com"
}
}'
```
```json title="Response" maxLines="15" theme={null}
{
"brand_name": null,
"id": "acct_01jpqjvfg9enpt7pyxd60pcmxj",
"name": "DT Precision Auto",
"organization": {
"address": {
"country": "US",
"line1": "2640 Huron St",
"line2": null,
"locality": "Los Angeles",
"name": "DT Precision Auto",
"postal_code": "90065",
"region": "CA"
},
"contact": {
"email": "dom@dtprecisionauto.com",
"first_name": "Dominic",
"last_name": "Toretto",
"phone_number": "+13235556439",
"title": null,
"title_other": null
},
"country": null,
"email": null,
"identifier": null,
"identifier_type": null,
"industry": "automotive",
"mobile_number": null,
"regions_of_operation": [],
"registered_name": null,
"stock_exchange": null,
"stock_symbol": null,
"type": "llc",
"website": "https://dtprecisionauto.com"
},
"time_zone": null
}
```
This step allows you to check for missing or invalid fields on the account that must be provided or fixed before it is ready to register a campaign.
See "[Check account status](/api-reference/endpoint/accounts/check-status)".
This example checks the local messaging capability of the account created in the previous example.
```sh title="Request" maxLines="15" theme={null}
curl -G https://api.surge.app/accounts/acct_01jpqjvfg9enpt7pyxd60pcmxj/status?capabilities=local_messaging \
-H "Authorization: Bearer "
```
```json title="Response - initial" maxLines="15" theme={null}
{
"capabilities": {
"local_messaging": {
"errors": [],
"fields_needed": [
"organization.contact.title",
"organization.country",
"organization.identifier",
"organization.identifier_type",
"organization.regions_of_operation",
"organization.registered_name"
],
"status": "incomplete"
}
}
}
```
```json title="Response - fixed" maxLines="15" theme={null}
{
"capabilities": {
"local_messaging": {
"errors": [],
"fields_needed": [],
"status": "ready"
}
}
}
```
If the capability request did not return a ready status, you'll need to update the account to fix missing or broken fields. As mentioned in the "Create an account" step, fixing fields can uncover additional fields that need changed, so you may need to repeat this step and the previous until the account is ready for local messaging.
See "[Update an account](/api-reference/endpoint/accounts/update)".
This example provides the missing fields from the example in the previous step.
```sh title="Request" maxLines="15" theme={null}
curl -X PATCH https://api.surge.app/accounts/acct_01jpqjvfg9enpt7pyxd60pcmxj \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"organization": {
"contact": {
"title": "other",
"title_other": "Owner"
},
"country": "US",
"identifier": "123456789",
"identifier_type": "ein",
"regions_of_operation": ["usa_and_canada"],
"registered_name": "DT Precision Auto LLC",
}
}'
```
```json title="Response" maxLines="15" theme={null}
{
"brand_name": null,
"id": "acct_01jpqjvfg9enpt7pyxd60pcmxj",
"name": "DT Precision Auto",
"organization": {
"address": {
"country": "US",
"line1": "2640 Huron St",
"line2": null,
"locality": "Los Angeles",
"name": "DT Precision Auto",
"postal_code": "90065",
"region": "CA"
},
"contact": {
"email": "dom@dtprecisionauto.com",
"first_name": "Dominic",
"last_name": "Toretto",
"phone_number": "+13235556439",
"title": "other",
"title_other": "Owner"
},
"country": "US",
"email": "dom@dtprecisionauto.com",
"identifier": "123456789",
"identifier_type": "ein",
"industry": "automotive",
"mobile_number": null,
"regions_of_operation": [
"usa_and_canada"
],
"registered_name": "DT Precision Auto LLC",
"stock_exchange": null,
"stock_symbol": null,
"type": "llc",
"website": "https://dtprecisionauto.com"
},
"time_zone": null
}
```
Once the account is ready for local messaging you can create a campaign documenting its intended messaging use case.
See "[Create a campaign](/api-reference/endpoint/campaigns/create)".
```sh title="Request" maxLines="15" theme={null}
curl -X POST https://api.surge.app/accounts/acct_01jpqjvfg9enpt7pyxd60pcmxj/campaigns \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"consent_flow": "When customers bring in their car for service, they will fill out this web form for intake: https://fastauto.shop/bp108c In it they can choose to opt in to text message notifications. If they choose to opt in, we will send them notifications to let them know if our mechanics find issues and once the car is ready to go, as well as links to invoices and to leave us feedback.",
"description": "This phone number will send auto maintenance notifications to end users that have opted in. It will also be used for responding to customer inquiries and sending some marketing offers.",
"message_samples": [
"You are now opted in to receive repair notifications from DT Precision Auto. Frequency varies. Msg&data rates apply. Reply STOP to opt out.",
"You’re lucky that hundred shot of NOS didn’t blow the welds on the intake!",
"Your car is ready to go. See your invoice here: https://l.fastauto.shop/s034ij"
],
"privacy_policy_url": "https://fastauto.shop/sms-privacy",
"use_cases": [
"account_notification",
"customer_care",
"marketing"
],
"volume": "high",
"includes": [
"links",
"phone_numbers"
],
"link_sample": "https://l.fastauto.shop/s034ij",
"terms_and_conditions_url": "https://fastauto.shop/terms-and-conditions"
}'
```
```json title="Response" maxLines="15" theme={null}
{
"consent_flow": "When customers bring in their car for service, they will fill out this web form for intake: https://fastauto.shop/bp108c In it they can choose to opt in to text message notifications. If they choose to opt in, we will send them notifications to let them know if our mechanics find issues and once the car is ready to go, as well as links to invoices and to leave us feedback.",
"description": "This phone number will send auto maintenance notifications to end users that have opted in. It will also be used for responding to customer inquiries and sending some marketing offers.",
"id": "cpn_01k0qczvhbet4azgn5xm2ccfst",
"includes": [
"links",
"phone_numbers"
],
"message_samples": [
"You are now opted in to receive repair notifications from DT Precision Auto. Frequency varies. Msg&data rates apply. Reply STOP to opt out.",
"You’re lucky that hundred shot of NOS didn’t blow the welds on the intake!",
"Your car is ready to go. See your invoice here: https://l.fastauto.shop/s034ij"
],
"privacy_policy_url": "https://fastauto.shop/sms-privacy",
"use_cases": [
"account_notification",
"customer_care",
"marketing"
],
"volume": "high",
"link_sample": "https://l.fastauto.shop/s034ij",
"terms_and_conditions_url": "https://fastauto.shop/terms-and-conditions"
}
```
While you await campaign approval, you can purchase a phone number for the account, and it will be ready to send text messages when the campaign is approved.
See "[Create a phone number](/api-reference/endpoint/phone-numbers/purchase)".
```sh title="Request" theme={null}
curl -X POST https://api.surge.app/accounts/acct_01jpqjvfg9enpt7pyxd60pcmxj/phone_numbers \
-H "Authorization: Bearer " \
-H "Content-Type: application/json" \
-d '{
"type": "local",
"area_code": "323"
}'
```
```json title="Response" maxLines="15" theme={null}
{
"id": "pn_01jsjwe4d9fx3tpymgtg958d9w",
"number": "+18015551234",
"type": "local"
}
```
# Authentication
Source: https://docs.surge.app/ui/authentication
Surge aims to be easy to use but also to provide for evolving security needs. To that end, embedded
UI components can be authenticated in two ways: a long-lived token shared by the various users in
an account, or a short-lived per-user token that will need to be rotated frequently.
## Which token type should I use?
Publishable account tokens are much easier to start with, but signed user tokens offer stronger
security.
| | Publishable token | Signed token |
| ------------ | ----------------- | ------------ |
| Ease of use | easy | harder |
| Security | weaker | strong |
| Availability | HQ only | API |
| Longevity | infinite | up to 1 hour |
| Scope | account | user |
## Publishable tokens
Our sample iframe snippets here in the docs and in HQ use a publishable token. This token belongs
to the account and can be used to authenticate any user in that account. Component URLs using this
authentication method must have both "token" and "user\_id" query parameters. An inbox URL, for
example, will look like this:
```
https://embed.surge.app/conversations?user_id=usr_01jz3d51beesrr3zryp246cj0s&token=atok_live_7db4gv7yqw6o4opijyqes2agl4noofgjycrmufjf7mtovs5u32uwuz
```
## Signed tokens
When you're ready to invest in added security for your embedded UI components, signed tokens belong
to a specific user and are only valid for a limited duration.
There are two ways to generate these tokens: you can sign your own, or you can have Surge sign them
for you. Having Surge sign your tokens is less involved, but it requires an API request, which will
not be as performant as signing tokens on your own server. A guide to self-signed tokens is
forthcoming, but the endpoint for Surge-signed tokens is
[POST /users/:user\_id/tokens](/api-reference/endpoint/tokens/create-token).
Component URLs using signed tokens need only the "token" query parameter. Since the token belongs
to a user, a "user\_id" query parameter would serve no purpose. The inbox URL from above, using
instead a signed token, will look like this:
```
https://embed.surge.app/conversations?token=eyJhbGciOiJFZERTQSIsImtpZCI6InNnbl8wMWp5bWowZ3AwZjNidmJmMmpyazRoYnd0ayIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTA4ODkyMDgsInN1YiI6InVzcl8wMWp5bWdkZnJwZWMyYXNjNW0wejNhNmZyOSJ9.zKayo3EDrUm1Hw8URrofuYwajgyTu6dH2H0FEuRExprP1IV66FHa8wC3SfdzV7sR3AjDGAwkuAXztScq6rBnBw
```
### Rotating signed tokens
Because signed tokens are short-lived they may expire while users are still interacting with the
embedded UI components authenticated with the expiring tokens. Connections will remain
authenticated after their token has expired, but any reconnects will trigger re-authentication. We
recommend rotating tokens just before they expire to ensure your components will continue to work.
#### Token expiring warning
When an embedded UI component is authenticated with a token that is about to expire, it will emit
an event warning of the pending expiration. This event will have the the type "token\_expiring":
```json theme={null}
{
"source": "surge_inbox",
"type": "token_expiring",
"data": {
"seconds_remaining": 15
}
}
```
#### Updating a component's token
Re-rendering the iframe with a new token in the URL could cause the component to lose necessary
state, so embedded components also support an "update\_token" message back into the iframe.
```json theme={null}
{
"type": "update_token",
"data": {
"token": "eyJhbGciOiJFZERTQSIsImtpZCI6InNnbl8wMWp5bWowZ3AwZjNidmJmMmpyazRoYnd0ayIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTA4ODkyMDgsInN1YiI6InVzcl8wMWp5bWdkZnJwZWMyYXNjNW0wejNhNmZyOSJ9.zKayo3EDrUm1Hw8URrofuYwajgyTu6dH2H0FEuRExprP1IV66FHa8wC3SfdzV7sR3AjDGAwkuAXztScq6rBnBw"
}
}
```
#### Example
Here's an example snippet of some JavaScript in your app for rotating tokens before they expire. In
this example `refreshSurgeToken` is a made-up function that makes a request to your server for a new
token.
```js theme={null}
const surgeInbox = document.querySelector('iframe#surge-inbox');
window.addEventListener('message', async ({ data, origin }) => {
if (origin == 'https://embed.surge.app') {
const { type } = data;
if (type == 'token_expiring') {
const { token } = await refreshSurgeToken();
const message = { type: 'update_token', data: { token }};
surgeInbox.contentWindow.postMessage(message, origin);
}
}
});
```
# Conversation
Source: https://docs.surge.app/ui/components/conversation
The conversation component displays the messages and attachments in a single conversation and a composer that allows the user to send new messages in that conversation.
The conversation component displays the messages and attachments in a single
conversation and a composer that allows the user to send new messages in that
conversation. It is often a good choice for embedding in customer detail pages
where you don't want to display all of the possible conversations, but want your
users to be able to easily message the customer they're currently viewing.
## Installation
The conversation component requires one of the following:
* Surge Conversation ID
* Surge Contact ID
* Phone Number
The conversation ID is the preferred method, and it will be the most performant
as the other methods will redirect to the conversation ID when one exists, so
the iframe may take longer to load.
### With a conversation ID
The simplest version of the conversation component can be embedded like this:
```html theme={null}
```
Both `{SURGE_USER_ID}` and `{ACCOUNT_TOKEN}` are required parameters. You can find
them in the Surge dashboard. We will also be providing more robust auth options
in the near future.
The `{CONVERSATION_ID}` parameter is also required and should be the ID of the
conversation to display.
### With a contact ID
```html theme={null}
```
Both `{SURGE_USER_ID}` and `{ACCOUNT_TOKEN}` are required parameters. You can find
them in the Surge dashboard. We will also be providing more robust auth options
in the near future.
The `{CONTACT_ID}` is also required in this instance and should be the ID of the
contact whose conversation should be displayed.
### With a phone number
```html theme={null}
```
Both `{SURGE_USER_ID}` and `{ACCOUNT_TOKEN}` are required parameters. You can find
them in the Surge dashboard. We will also be providing more robust auth options
in the near future.
The `{PHONE_NUMBER}` is the phone number for the person whose conversation
should be displayed, or to whom messages should be sent if no conversation
exists. This parameter is required.
The `{FIRST_NAME}` and `{LAST_NAME}` parameters are optional, but highly
encouraged as they will allow the contact's information to be displayed properly
in the inbox. If no contact or conversation exists yet for the given phone
number, these parameters will be attached to the contact when a message is sent
and the contact is created.
# Inbox
Source: https://docs.surge.app/ui/components/inbox
The inbox component provides a full messenger interface in a single component.
For many applications, this will be the only component you need to integrate to
get started. It should be noted too that the component is fully responsive. If
embedded in a narrow width sidebar for instance, it will collapse down to show
a smaller mobile-style view.
## Installation
The simplest version of the inbox component can be embedded like this:
```html theme={null}
```
Both `{SURGE_USER_ID}` and `{ACCOUNT_TOKEN}` are required parameters. You can find
them in the Surge dashboard. We will also be providing more robust auth options
in the near future.
The `{PHONE_NUMBER_ID}` parameter is optional. If provided, the inbox will only
display conversations associated with the specified phone number. This is
particularly useful for accounts with multiple phone numbers being used by
different groups of people.
## Events
The Inbox component emits events that you can listen to in your application. Here
are the events that you can listen to:
### Conversation selected
When the user selects a conversation, this event is emitted with the details of
the conversation:
```json theme={null}
{
"source": "surge-inbox",
"type": "conversation-selected",
"conversation": %{
"id": "cnv_01jadpja6sen796q4wxygg5q78",
"contact": {
"id": "ctc_01jadpk0asfq599vt3pwn3he6x",
"first_name": "Dominic",
"last_name": "Toretto",
"phone_number": "+18015551234"
}
}
}
```
### Conversation deselected
When the user selects a conversation or begins a new one, this event is emitted
with the details of the conversation that was previously selected:
```json theme={null}
{
"source": "surge-inbox",
"type": "conversation-deselected",
"conversation": {
"id": "cnv_01jadpja6sen796q4wxygg5q78",
"contact": {
"id": "ctc_01jadpk0asfq599vt3pwn3he6x",
"first_name": "Dominic",
"last_name": "Toretto",
"phone_number": "+18015551234"
}
}
}
```
### Filter changed
When the user selects an inbox filter, this event is emitted with the new selection.
```json theme={null}
{
"source": "surge-inbox",
"type": "filter-changed",
"filter": "unread"
}
```
The `filter` will be one of `inbox`, `unread`, `all`, `archived`, or `opt_outs`.
## Events accepted
The Inbox component also accepts events to provide basic controls for
your application. Here are the events you can send:
### Update composer
Update the content in the user's composer.
```json theme={null}
{
"target": "surge-inbox",
"type": "update-composer",
"method": "replace",
"text": "this should be the only text"
}
```
The `method` can be one of `replace` or `append`:
* `replace` scraps any existing content and leaves just the included text
* `append` adds the included text at the end of the existing text content
# Unread Count
Source: https://docs.surge.app/ui/components/unread-count
The unread count component displays a count of all the unread messages for a given user.
The unread count component displays a count of all the unread messages for a
given user. It will typically be embedded in your main menu or sidebar to call
attention to any unread messages to which the user should respond.
The component will hide itself if there are no unread messages and display the
count whenever unread messages are received. This allows you to always have the
iframe displayed on your page.
## Installation
The simplest version of the unread count component can be embedded like this:
```html theme={null}
```
Both `{SURGE_USER_ID}` and `{ACCOUNT_TOKEN}` are required parameters. You can find
them in the Surge dashboard. We will also be providing more robust auth options
in the near future.
The `{CONVERSATION_ID}` parameter is optional. If provided, the unread count
will only display unread messages for that specific conversation. If not
provided, the unread count will display unread messages across all conversations
to which the user has access.
### Styling
With this component, we recommend styling the iframe to allow for automatic
expansion. We recommend giving the link container relative positioning so that
the iframe can have absolute positioning to allow it to be positioned in the
bottom right corner of the link. This allows the button icon to remain centered
within the container while the unread count floats over the top of it.
Using Tailwind CSS, that can be accomplished like this:
```html theme={null}
Messages
```
## Events
The Unread Count component emits events that you can listen to in your
application. Here are the events that you can listen to:
### Count Updated
Whenever the user reads an unread conversation or receives a new message, this event
will be emitted with the updated unread count:
```json theme={null}
{
"source": "surge-unread-count",
"type": "count-updated",
"count": 3
}
```
# Introduction
Source: https://docs.surge.app/ui/introduction
Introduction to the UI components provided by Surge
Surge provides various UI components that can be embedded in your application to
help you provide communications capabilities to your customers. These components
are all designed to be easy to integrate, while also providing deeper
integrations with slightly more effort.
The components are currently offered as iframes, and more customizable React
components are available upon request. If you have any feedback or need help,
please reach out to us at [support@surge.app](mailto:support@surge.app).
All of these components are under active development, so you can expect that
after integrating, you will continue to gain new features without having to do
any extra work. This also means that components are subject to change, so you
may see differences in their design over time.