Blackleaf API Developer Guide: Templates, SMS, Webhooks, Contacts and Automations

Quick answer

What is the recommended way to send a text through the Blackleaf API?

Create the message as a reusable template with POST /messaging/create/template. Confirm that the returned template is accepted, store its id, and send future messages with POST /messaging/send/text using that value as templateId.

Pass customer-specific values, order information, links, sender selection, and other runtime data separately. This keeps the reviewed message structure stable while allowing each send to be personalized.

The Blackleaf API is a REST API for messaging, contacts, campaigns, automations, sender profiles, 2FA, account data, and reporting. Production requests use the base URL https://api.blackleaf.io, Bearer authentication, JSON request bodies, and JSON responses.

AuthenticateSend the API token from a trusted server.
Create templateSubmit the stable message structure.
Check approvalDo not send until the template is usable.
Send by IDPass the recipient and runtime data.
Track eventsProcess delivery and inbound webhooks.

Use the interactive Blackleaf API documentation as the current endpoint reference. This guide explains how the pieces should be used together in a production integration.

Choose the correct Blackleaf messaging workflow

Not every message should be implemented as a direct API send. Start by identifying the operational model.

Use case Recommended workflow Primary endpoint
Order update, receipt, reminder, account notice, or another repeated transactional message Create an approved template once, then send it by templateId. POST /messaging/create/template
POST /messaging/send/text
Unique message whose complete wording cannot be known in advance Send dynamic content only when a reusable template cannot represent the use case. Content is evaluated at send time. POST /messaging/send/text
One message to a planned audience Configure a campaign, then start, pause, or cancel it through its campaign endpoint. POST /campaign/{_id}/send/
Multi-step workflow triggered by an event Configure an automation, then invoke it with a contact and event payload. POST /automation/{_id}/invoke/
Login or security verification Use the dedicated 2FA send and verification endpoints. POST /messaging/send/2fa
POST /messaging/verify/2fa
Default production rule

If the message has a repeatable structure, make it a template. Do not rebuild the full message body for every recipient when variables can represent the changing data.

Authenticate with a Bearer token

Every documented API operation requires an Authorization header containing a Bearer token.

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Keep the token in a server-side secret manager or protected environment variable. Do not place it in browser JavaScript, a mobile application bundle, a public repository, logs, screenshots, support tickets, or customer-visible error messages.

A safe first request is the account-balance endpoint because it verifies the production base URL and token without creating a contact or sending a message.

curl --request GET \
  --url "https://api.blackleaf.io/account/balance" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Accept: application/json"
const response = await fetch("https://api.blackleaf.io/account/balance", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.BLACKLEAF_API_KEY}`,
    Accept: "application/json"
  }
});

const result = await response.json();

if (!response.ok) {
  throw new Error(`Blackleaf request failed with HTTP ${response.status}`);
}

console.log(result.balance);
Do not proxy arbitrary client requests

Your backend should decide which Blackleaf operations are allowed. Do not expose a generic endpoint that accepts any destination, message body, template ID, or campaign ID from an untrusted client.

Step 1: Create the message template

Create a template with POST /messaging/create/template. The request can include a message body, an optional image, and unsubscribeText.

The template body may contain supported placeholders. The API documentation uses {{firstName}} and {{url}} as examples.

curl --request POST \
  --url "https://api.blackleaf.io/messaging/create/template" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "body": "Example Store: Hi {{firstName}}, your order is ready. View details: {{url}}",
    "unsubscribeText": "Reply STOP to end"
  }'

A successful template response includes fields such as:

{
  "id": "TEMPLATE_ID",
  "accepted": true,
  "bodyAccepted": true,
  "imageAccepted": true,
  "status": "accepted",
  "explanation": "Your template has been accepted."
}

Do not treat an HTTP 200 response by itself as proof that the template is ready. Check accepted, bodyAccepted, imageAccepted, status, and explanation. A template may be created while some or all of its content is not accepted for sending.

Store the template ID

Save the returned id in your configuration or database. Associate it with a stable internal name such as order_ready_v1.

Version content changes

If the fixed wording, image, or required disclosure changes materially, create and approve a new template version before moving production traffic to it.

Keep variables narrow

Use variables for values such as a first name or destination URL. Do not place the entire message inside one unrestricted variable.

Promote only accepted templates

Treat template acceptance like a deployment gate. Production code should reference only a template ID that has completed review successfully.

The public API reference does not currently document an idempotency key for template creation. Prevent accidental duplicates by recording your own logical template name, version, content hash, returned ID, status, and creation time.

Step 2: Send the accepted template

Send an SMS or MMS with POST /messaging/send/text. For the normal production workflow, provide the recipient in to, the approved template ID in templateId, and any data needed to resolve the template placeholders.

curl --request POST \
  --url "https://api.blackleaf.io/messaging/send/text" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "to": "+15551234567",
    "templateId": "TEMPLATE_ID",
    "contact": {
      "firstName": "Jordan",
      "lastName": "Lee"
    },
    "landingUrl": "https://example.com/orders/12345",
    "sendingProfileId": "SENDER_PROFILE_ID"
  }'
async function sendOrderReadyText({ phone, firstName, orderUrl }) {
  const response = await fetch(
    "https://api.blackleaf.io/messaging/send/text",
    {
      method: "POST",
      headers: {
        Authorization: `Bearer ${process.env.BLACKLEAF_API_KEY}`,
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: JSON.stringify({
        to: phone,
        templateId: process.env.BLACKLEAF_ORDER_READY_TEMPLATE_ID,
        contact: { firstName },
        landingUrl: orderUrl,
        sendingProfileId: process.env.BLACKLEAF_SENDER_PROFILE_ID
      })
    }
  );

  const raw = await response.text();
  let result;

  try {
    result = raw ? JSON.parse(raw) : {};
  } catch {
    result = { raw };
  }

  if (!response.ok) {
    const error = new Error(`Blackleaf send failed with HTTP ${response.status}`);
    error.status = response.status;
    error.details = result;
    throw error;
  }

  return result;
}

The send response includes an id and a status. Store the message ID with the business event that caused the send, such as the order ID, customer ID, notification type, and timestamp.

An accepted send is not the same as a delivered message

The initial API response confirms that Blackleaf accepted the request for processing. Final delivery happens asynchronously. Use message-status webhooks or retrieve message records to learn whether the carrier delivered, filtered, failed, or otherwise updated the message.

Fields supported by the send endpoint

The live API reference documents the following request fields for POST /messaging/send/text.

Field Type How to use it
to String The recipient phone number. Normalize and store phone numbers consistently, preferably in E.164 format.
templateId String The ID returned by the template-creation endpoint. Use this for repeatable production messages.
body String Raw message content for sends that cannot use a reusable template. Content is evaluated at send time.
image String An image reference for MMS. Prefer placing repeatable creative in the reviewed template.
contact Object Runtime customer data, such as firstName and lastName, used by supported placeholders and workflows.
order Object Runtime order context, such as order status or total, when the configured message or workflow uses it.
landingUrl String The destination URL supplied to a supported URL placeholder or landing-page flow.
landingImage String Optional image content for the associated landing experience.
landingBody String Optional body content for the associated landing experience.
campaignId String Optional campaign context when the send belongs to a configured campaign workflow.
sendingProfileId String Selects the configured sender profile that should route the message.
dob String Optional date-of-birth context in the format expected by the configured age-aware workflow.

Only send fields your integration actually uses. Treat the interactive API documentation and the configuration of the specific Blackleaf account as the source of truth for supported placeholders, landing experiences, sender profiles, and age-aware behavior.

Why templates should be the default

Blackleaf evaluates message content because regulated and carrier-sensitive messaging cannot be treated as an unrestricted pipe. Templates make that review reusable.

Consideration Approved template Raw body at send time
Best use Repeatable transactional, lifecycle, loyalty, support, and notification messages Truly unique content that cannot be represented safely with a template
Review timing Template is evaluated before production sends use its ID Content is evaluated when the send is requested
Consistency Fixed structure with controlled runtime values Complete body can change on every request
Operational risk Lower risk of an unexpected content change reaching production Requires stronger application-side validation and monitoring
Recommended production pattern Default Exception

If a customer asks whether raw message bodies are supported, the practical answer is yes for content that must be created dynamically, but templates are the preferred path whenever the structure can be known in advance.

Select a sender profile

A sender profile represents the Blackleaf sending configuration used to route a message. Retrieve available profiles with GET /messaging/senders/profiles.

curl --request GET \
  --url "https://api.blackleaf.io/messaging/senders/profiles?pageSize=100&page=0" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Accept: application/json"

The response is paginated and contains an items array. Each documented profile includes fields such as _id, title, healthy, sticky, dateCreated, and dateModified.

Store the selected profile’s _id and pass it as sendingProfileId when the application must choose a specific profile. Do not hard-code an ID copied from another Blackleaf organization or environment.

Create, update, retrieve, subscribe, and unsubscribe contacts

Blackleaf provides contact endpoints for synchronizing customer identity, profile, subscription status, and rewards data.

Operation Endpoint Purpose
List contacts GET /contact/ Retrieve contacts with filters and pagination.
Get one contact GET /contact/{phone} Retrieve a contact by phone number.
Create or update POST /contact/set Upsert a contact using phone, email, customer ID, or other supplied identity data.
Subscribe POST /contact/{phone}/subscribe Set the Blackleaf contact to a subscribed state.
Unsubscribe POST /contact/{phone}/unsubscribe Suppress future messaging to the contact.
Adjust rewards POST /contact/{phone}/points Add or remove points with a title and description.

Upsert a contact

curl --request POST \
  --url "https://api.blackleaf.io/contact/set" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "customerId": "customer_12345",
    "phone": "+15551234567",
    "email": "jordan@example.com",
    "firstName": "Jordan",
    "lastName": "Lee",
    "dob": "1990-05-20T00:00:00.000",
    "consumerType": "AdultUse"
  }'

The contact upsert endpoint can identify and update a contact by phone number, email, or customer ID. Use a stable customerId from the source system whenever one exists, and normalize phone numbers before synchronization.

A subscribe request is not a substitute for consent evidence

Only call the subscribe endpoint after the business has a valid basis to mark the person subscribed for the intended message type. Retain the opt-in disclosure, source, timestamp, customer action, and other evidence required by the business’s compliance process. Registration and API access do not turn every phone number in a POS or CRM into an eligible marketing recipient.

When a customer opts out, process the change immediately and synchronize it back to every system that can initiate a send. Review Blackleaf’s SMS opt-in and consent guide and dispensary SMS compliance framework before launching production marketing traffic.

Invoke and manage campaigns through the API

Use a campaign when Blackleaf should manage one message across a defined audience. The API supports listing, creating or modifying, starting, pausing, and canceling campaigns.

Operation Endpoint
List campaignsGET /campaign/
Create or modify a campaignPOST /campaign/set
Add contactsPOST /campaign/contact/add
Remove contactsPOST /campaign/contact/remove
Start sendingPOST /campaign/{_id}/send/
PausePOST /campaign/{_id}/pause/
Cancel or deletePOST /campaign/{_id}/cancel/

For most integrations, the safest path is to configure and review the campaign in Blackleaf, retain its campaign ID, and invoke the resulting endpoint from the external system.

curl --request POST \
  --url "https://api.blackleaf.io/campaign/CAMPAIGN_ID/send/" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Accept: application/json"

The documented response contains a status such as Started. Starting a campaign is an operational action, so protect the endpoint with application authorization, prevent duplicate operator actions, log the initiating user or event, and verify the campaign’s audience and state before invoking it.

If the application needs to build campaigns entirely through the API, follow the current campaign schema in the interactive documentation. Campaign configuration contains significantly more state than a single-message send and should not be reduced to a guessed minimal payload.

Invoke an automation from a POS, ecommerce platform, or backend

Use POST /automation/{_id}/invoke/ when an external event should enter a workflow already configured in Blackleaf. The request contains a contact object and an optional payload object.

curl --request POST \
  --url "https://api.blackleaf.io/automation/AUTOMATION_ID/invoke/" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "contact": {
      "customerId": "customer_12345",
      "phone": "+15551234567",
      "firstName": "Jordan",
      "lastName": "Lee"
    },
    "payload": {
      "eventId": "order_98765_ready",
      "orderId": "98765",
      "status": "Ready for Pickup"
    }
  }'

The documented success response contains {"status":"Started"}.

Include a stable event identifier in the payload even when the current workflow does not display it. Your application can use that value to prevent the same source event from invoking the automation twice and to trace a customer question back to the originating system.

Keep workflow logic in the right system

The source application should decide that a real event occurred. Blackleaf should manage the configured messaging workflow that follows. Do not trigger an automation merely because a page was refreshed or a webhook was delivered more than once.

Send and verify two-factor authentication codes

Blackleaf provides dedicated endpoints for one-time security codes. Do not build 2FA by generating a code and inserting it into a marketing-message template.

Send a code

curl --request POST \
  --url "https://api.blackleaf.io/messaging/send/2fa" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "phone": "+15551234567",
    "digits": 6,
    "expires": 300
  }'

Verify a submitted code

curl --request POST \
  --url "https://api.blackleaf.io/messaging/verify/2fa" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "phone": "+15551234567",
    "code": 123456
  }'

The send endpoint documents phone, digits, and expires. The verification endpoint requires the phone number and submitted code. Apply application-level controls for repeated requests, failed attempts, session binding, and abuse prevention.

Retrieve messages and synchronize records

Use GET /messaging/messages to retrieve message records. The endpoint supports:

  • campaignId to filter messages associated with a campaign
  • pageSize from 1 to 1,000
  • page, beginning with page 0
  • lastModified as a UTC ISO 8601 timestamp
  • sort as asc or desc
curl --request GET \
  --url "https://api.blackleaf.io/messaging/messages?pageSize=100&page=0&sort=asc&lastModified=2026-08-01T00%3A00%3A00Z" \
  --header "Authorization: Bearer $BLACKLEAF_API_KEY" \
  --header "Accept: application/json"

Paginated list responses contain items, page, pageSize, totalItems, and hasMoreItems. Continue requesting the next page until hasMoreItems is false.

A message record may contain the message ID, destination, source number, template ID, body, image, campaign context, sender profile, carrier, delivery status, message type, number of parts, cost, and created or modified timestamps.

Use a safe incremental-sync cursor

When synchronizing by lastModified, save the newest successfully processed timestamp only after the complete page or batch is committed. Re-read a small overlap window and upsert by Blackleaf message ID so records modified near a page boundary are not lost.

Process message-status and inbound-message webhooks

Polling is useful for reconciliation, but webhooks are the preferred way to receive real-time delivery changes and customer replies.

Message-status webhook

A message-status webhook is sent when delivery status changes. The documented payload can include:

{
  "org": "org_12345",
  "messageId": "a1b2c3d4e5",
  "dateModifiedLong": 1759935198703,
  "status": "delivered",
  "carrier": "Verizon",
  "from": "+15551234567",
  "to": "+15559876543",
  "errorData": {
    "code": "30007",
    "description": "Carrier filtering"
  }
}

Use messageId to correlate the event with the ID returned by the original send request. The errorData object is included when the carrier reports a failure or filtering issue.

Inbound-message webhook

An inbound webhook is sent when a recipient replies. The documented payload can include:

{
  "to": "+15551234567",
  "from": "+15559876543",
  "org": "org_12345",
  "body": "Is my order ready?",
  "messageId": "d3e4f5g6h7",
  "type": "inbound",
  "dateCreated": "2026-08-18T18:20:00.000Z"
}

Acknowledge a valid webhook with 200 OK. The documentation notes that failing to acknowledge an inbound event may result in retries or duplicate delivery.

Webhook handler checklist
  • Expose an HTTPS endpoint that can accept JSON POST requests.
  • Read the raw request safely and reject payloads that exceed your expected size.
  • Validate the event using the authentication or verification method configured for your account.
  • Store and deduplicate events before triggering downstream work.
  • Respond quickly with 200 OK, then perform slower processing asynchronously.
  • Treat webhook order as non-authoritative. A later delivery state should not be overwritten by an older event.
  • Keep failed events in a retryable queue and preserve the original payload for investigation.
  • Do not log complete customer message bodies unless the business has approved that retention.

The public documentation describes the webhook payloads but does not publish one universal webhook-secret format or configuration endpoint. Use the webhook setup and verification method supplied for the specific Blackleaf account rather than inventing a signature header.

Blackleaf API endpoint map

The current API documentation groups operations into messaging, automations, campaigns, contacts, products, orders, account data, and analytics.

Area Endpoints Typical integration use
Messaging /messaging/create/template
/messaging/send/text
/messaging/send/2fa
/messaging/verify/2fa
/messaging/messages
/messaging/senders/profiles
Create reviewed content, send SMS or MMS, handle security codes, retrieve message history, and select sender profiles.
Automations /automation/{_id}/invoke/ Trigger a configured workflow from a POS, ecommerce event, CRM, data warehouse, or application backend.
Campaigns /campaign/
/campaign/set
/campaign/contact/add
/campaign/contact/remove
/campaign/{_id}/send/
/campaign/{_id}/pause/
/campaign/{_id}/cancel/
Create, inspect, populate, start, pause, and cancel audience-based sends.
Contacts /contact/
/contact/{phone}
/contact/set
/contact/{phone}/subscribe
/contact/{phone}/unsubscribe
/contact/{phone}/points
Synchronize customer profiles, subscription state, and rewards activity.
Products and orders /product/
/product/{id}
/order/
/order/{id}
Retrieve commerce data available to the account.
Account /account/balance Retrieve organization, balance, and documented automatic-funding configuration fields.
Analytics /analytics/summary/
/analytics/messaging/
/analytics/orders/
/analytics/inventory/report-card/
Retrieve account, messaging, order, and inventory-related reporting available to the account.

Use the exact path shown in the live API reference. Several endpoints intentionally include a trailing slash. Do not assume that a different path, method, or legacy query-string version is equivalent.

How to design a production Blackleaf integration

1. Separate configuration from runtime data

Store API tokens, template IDs, automation IDs, campaign IDs, and sender profile IDs as protected configuration. Pass customer, order, link, and event values at runtime.

2. Create an application-side message key

Before calling Blackleaf, assign the business event a stable key such as order_98765_ready_v1. Record the event key, recipient, template ID, request time, Blackleaf message ID, initial status, and final delivery state.

3. Prevent duplicate sends before making the request

The public API reference does not document a client-supplied idempotency header for message sends. Enforce uniqueness in your own database before sending. A unique constraint on the source event and notification type is stronger than an in-memory flag.

4. Do not blindly retry an uncertain send

If the connection times out after the request leaves your server, the message may already have been accepted. A blind retry can produce a duplicate. Mark the attempt as uncertain, reconcile against message records where possible, and use a controlled recovery process.

5. Treat delivery as asynchronous state

Model message state separately from the HTTP request. Store the initial response, update the record from webhooks, and reconcile through GET /messaging/messages.

6. Normalize identity consistently

Use one phone-number normalization strategy across contacts, sends, orders, webhook matching, suppression, and customer support. Prefer E.164 storage, and do not create a second customer record merely because punctuation differs.

7. Keep suppression in the critical path

Before initiating a marketing send, verify that the customer is eligible for the specific use case. When an opt-out occurs, update Blackleaf and every external system that can trigger a message.

8. Monitor by template, sender, carrier, and workflow

Aggregate accepted, delivered, failed, filtered, and inbound events by template ID, sender profile, carrier, campaign, automation, and source event. A single account-wide delivery rate can hide a failing integration path.

Error handling and troubleshooting

Blackleaf uses standard HTTP response codes, but integration logic should preserve the response body because it may contain the most useful explanation.

Observed problem What to check Recommended response
Authentication request fails Production base URL, Bearer prefix, token value, account permissions, accidental whitespace, and whether the token was exposed or rotated Correct or rotate the credential. Do not retry repeatedly with the same rejected token.
Template is returned but not usable accepted, bodyAccepted, imageAccepted, status, and explanation Correct the rejected content and create a new reviewed template version.
Send request is accepted but the customer did not receive it Message-status webhook, message record, carrier, destination format, suppression, sender health, filtering information, and final delivery status Do not assume the initial API response means delivery. Investigate the asynchronous message state.
Template variable is blank Placeholder spelling, whether the correct runtime object was supplied, null values, and template version Validate required personalization fields before sending and reject incomplete application events.
Wrong sending configuration is used The sendingProfileId, account environment, and IDs stored in configuration Retrieve sender profiles from the same account and environment, then update the mapping.
Duplicate texts are sent Automatic retries, repeated source events, webhook-trigger loops, concurrent workers, and missing database uniqueness Add application-side idempotency before the Blackleaf call. Do not rely on process memory.
Inbound replies are missing Webhook URL, HTTPS availability, response codes, queue failures, event deduplication, and the account’s webhook configuration Acknowledge valid events quickly and move downstream work to a durable queue.
List synchronization misses or repeats records Zero-based page number, hasMoreItems, UTC timestamp format, sort direction, and the saved modified cursor Upsert by Blackleaf object ID and overlap the incremental-sync window.

When asking Blackleaf support to investigate, provide the organization, endpoint, approximate UTC time, Blackleaf message or object ID, HTTP status, sanitized response body, and the expected result. Do not send the API token or unnecessary customer data.

Production launch checklist

  • The integration uses https://api.blackleaf.io for production.
  • The API token is stored server-side and excluded from logs and source control.
  • Each repeatable message has an accepted template and a versioned internal mapping.
  • Production sends use templateId instead of rebuilding the body for every customer.
  • Required template variables are validated before the request is sent.
  • Phone numbers are normalized consistently.
  • The correct sender profile is selected for the account and workflow.
  • Consent, customer eligibility, and opt-out suppression are enforced before marketing sends.
  • Source events have application-side idempotency.
  • The initial send response and Blackleaf message ID are persisted.
  • Webhook endpoints acknowledge valid events quickly and process them idempotently.
  • A polling or reconciliation job checks for events that a webhook handler may have missed.
  • Retries distinguish a request that never left the server from a request with an uncertain outcome.
  • Rate limits and expected throughput have been confirmed for the account and use case.
  • Alerts exist for authentication failures, rejected templates, delivery degradation, queue failures, and repeated webhook errors.
  • Logs contain identifiers and timestamps without exposing tokens or unnecessary customer content.

Information needed to answer an API support question

Most integration questions can be answered quickly when the request includes the following details:

  1. The exact endpoint and HTTP method
  2. Whether the request uses production, test, or development
  3. The approximate request time in UTC
  4. The HTTP response status
  5. The sanitized response body
  6. The Blackleaf template, message, campaign, automation, or contact ID involved
  7. The expected behavior and the actual behavior
  8. Whether the issue happens consistently or only for certain recipients, carriers, templates, or sender profiles
  9. Whether a message-status or inbound webhook was received
  10. Whether retry logic may have run

Replace the API token and sensitive customer content before sharing an example. A useful sanitized request preserves field names, data types, endpoint paths, IDs relevant to the investigation, timestamps, and response details.

When an API question should be escalated

The documentation can answer how to authenticate, which endpoint to call, why templates are preferred, which fields are documented, how pagination works, and how delivery or inbound events are reported. Some questions depend on account configuration or platform-side data and should not be answered by guessing.

Question Can the guide answer it? Next step
Which authentication header should I send? Yes Use Authorization: Bearer YOUR_API_KEY.
Should I create a template before sending? Yes Use a template for every repeatable message structure.
Why does a successful API response not prove delivery? Yes Explain asynchronous carrier delivery and check the message status.
Which sending profile is enabled for this customer’s account? No, not from the article alone Retrieve the account’s sender profiles or inspect its Blackleaf configuration.
Why was this specific template rejected? Sometimes Start with the response’s acceptance fields and explanation. Escalate if the explanation is absent or unclear.
Why did one specific carrier filter a message? No, not conclusively Provide the message ID, carrier, UTC time, final status, error data, template ID, and sender profile for investigation.
What webhook signature or secret does this account use? No Use the verification method configured for the account or confirm it with Blackleaf.
What is this account’s exact rate limit or message throughput? No Confirm the account plan, campaign type, route, and expected production volume with Blackleaf.
Is an undocumented request field or placeholder supported? No Do not infer support from a similar field. Check the live schema or confirm with Blackleaf.
Support rule

Answer from the documented endpoint, observed response, and account configuration. If a conclusion requires information that is not present, ask for the missing details or escalate instead of inventing platform behavior.

Blackleaf API frequently asked questions

What is the fastest correct way to send a text with the Blackleaf API?

Create the repeatable message with POST /messaging/create/template, confirm it is accepted, save the returned template ID, and call POST /messaging/send/text with the recipient, templateId, and any runtime data.

Can I send a message body without creating a template?

Use a raw body only when the complete message cannot reasonably be represented by a reusable template. Raw content is evaluated at send time. If the structure is repeatable, an accepted template is the preferred production route.

Does a successful send response mean the text was delivered?

No. It means the request was accepted for processing. Delivery is asynchronous. Use the returned message ID, message-status webhooks, and GET /messaging/messages to track the final state.

How do I personalize an approved template?

Put supported placeholders in the template and pass the corresponding runtime values through fields such as contact, order, and landingUrl. Validate every required value before sending.

How do I send an MMS?

The template-creation and send endpoints support an image field. Include the image in the reviewed template when it is repeatable, confirm imageAccepted, and use the resulting template ID for production sends.

How do I choose which number sends the message?

Retrieve the account’s sender profiles with GET /messaging/senders/profiles and pass the selected profile’s ID as sendingProfileId. The profile controls the configured routing rather than the application supplying an arbitrary source phone number.

Should I call the Blackleaf API directly from a browser?

No. Make authenticated Blackleaf API calls from a trusted backend so the Bearer token is not exposed to the user or embedded in public client code.

What is the difference between a direct send, campaign, and automation?

A direct send delivers one message request to one recipient. A campaign manages a planned message across an audience. An automation starts a configured workflow from an event and can contain timing or additional steps.

How should an order-ready integration be built?

Create and approve an order-ready template, map it to an internal version, listen for the real order-ready event, enforce a unique event key, verify customer eligibility, call the send endpoint with the template ID and order data, store the returned message ID, and update delivery state from webhooks.

How do I stop a contact from receiving messages?

Call POST /contact/{phone}/unsubscribe and synchronize the opt-out to every external system that can initiate a send. Do not wait for a scheduled batch before suppressing future marketing messages.

Does calling the subscribe endpoint prove customer consent?

No. The endpoint updates contact state in Blackleaf. The business must separately retain evidence showing how and when the customer agreed to receive the intended type of messages.

How do I avoid duplicate messages?

Assign each source event a stable application-side key and enforce uniqueness in persistent storage before calling Blackleaf. Also deduplicate source webhooks, automation triggers, and retry jobs.

What should I do after a send request times out?

Do not immediately send the same request again. The first request may already have been accepted. Record the outcome as uncertain, reconcile message activity where possible, and use a controlled recovery process to avoid duplicates.

What are the API rate limits?

Rate limits and message throughput depend on the account plan and campaign type. Confirm the expected request rate, sending volume, and delivery requirements with Blackleaf before load testing or launching high-volume production traffic.

Where can I see the current endpoint schemas?

Use the interactive documentation at api.blackleaf.io. It contains the current methods, paths, request fields, examples, and response schemas.

Build messaging into your product without building carrier infrastructure

Blackleaf gives POS platforms, ecommerce systems, CRMs, data teams, and application developers one API for approved message templates, SMS and MMS, contacts, campaigns, automations, 2FA, delivery events, and customer replies.

Explore the Blackleaf API documentation or contact Blackleaf to review your integration.