- Quick answer
- Choose the correct Blackleaf messaging workflow
- Authenticate with a Bearer token
- Step 1: Create the message template
- Step 2: Send the accepted template
- Fields supported by the send endpoint
- Why templates should be the default
- Select a sender profile
- Create, update, retrieve, subscribe, and unsubscribe contacts
- Invoke and manage campaigns through the API
- Invoke an automation from a POS, ecommerce platform, or backend
- Send and verify two-factor authentication codes
- Retrieve messages and synchronize records
- Process message-status and inbound-message webhooks
- Blackleaf API endpoint map
- How to design a production Blackleaf integration
- Error handling and troubleshooting
- Production launch checklist
- Information needed to answer an API support question
- When an API question should be escalated
- Blackleaf API frequently asked questions
- Sources and further reading
- Build messaging into your product without building carrier infrastructure
Quick answer
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.
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/templatePOST /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/2faPOST /messaging/verify/2fa |
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);
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.
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.
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 campaigns | GET /campaign/ |
| Create or modify a campaign | POST /campaign/set |
| Add contacts | POST /campaign/contact/add |
| Remove contacts | POST /campaign/contact/remove |
| Start sending | POST /campaign/{_id}/send/ |
| Pause | POST /campaign/{_id}/pause/ |
| Cancel or delete | POST /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.
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:
campaignIdto filter messages associated with a campaignpageSizefrom 1 to 1,000page, beginning with page 0lastModifiedas a UTC ISO 8601 timestampsortasascordesc
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.
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.
- Expose an HTTPS endpoint that can accept JSON
POSTrequests. - 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.iofor 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
templateIdinstead 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:
- The exact endpoint and HTTP method
- Whether the request uses production, test, or development
- The approximate request time in UTC
- The HTTP response status
- The sanitized response body
- The Blackleaf template, message, campaign, automation, or contact ID involved
- The expected behavior and the actual behavior
- Whether the issue happens consistently or only for certain recipients, carriers, templates, or sender profiles
- Whether a message-status or inbound webhook was received
- 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. |
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.
Sources and further reading
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.