# 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 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. The inbox 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 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.