Send a rendered broadcast test
/v1/email/broadcasts/{broadcast_id}/testconst params = {
template: {
parameters: {
title: "Welcome",
offer: "OCTOBER20",
discount: 20,
featured: false,
},
},
contact_id: "con_01krdgeqcxet5s7t44vh8rt9mg",
};
const preview = await bird.broadcasts.preview(
"eb_01krdgeqcxet5s7t44vh8rt9mg",
params,
);
const accepted = await bird.broadcasts.test(
"eb_01krdgeqcxet5s7t44vh8rt9mg",
{
...params,
to: "member@example.com",
preview_fingerprint: preview.preview_fingerprint,
},
{ idempotencyKey: "broadcast-preview-intent-1" },
);
console.log(accepted.id, accepted.status);template = {
"parameters": {
"title": "Welcome",
"offer": "OCTOBER20",
"discount": 20,
"featured": False,
}
}
contact_id = "con_01krdgeqcxet5s7t44vh8rt9mg"
preview = client.broadcasts.preview(
"eb_01krdgeqcxet5s7t44vh8rt9mg", template=template, contact_id=contact_id
)
accepted = client.broadcasts.test(
"eb_01krdgeqcxet5s7t44vh8rt9mg",
template=template,
contact_id=contact_id,
to="member@example.com",
preview_fingerprint=preview.preview_fingerprint,
options={"idempotency_key": "broadcast-preview-intent-1"},
)
print(accepted.id, accepted.status)parameters := map[string]json.RawMessage{"title": json.RawMessage(`"Welcome"`), "offer": json.RawMessage(`"OCTOBER20"`), "discount": json.RawMessage(`20`), "featured": json.RawMessage(`false`)}
params := bird.BroadcastsValidateParams{Template: bird.Value(bird.BroadcastsParameterTemplate{Parameters: ¶meters})}
previewParams := bird.BroadcastsPreviewParams{BroadcastsValidateParams: params, ContactID: "con_01krdgeqcxet5s7t44vh8rt9mg"}
preview, err := client.Broadcasts.Preview(context.Background(), "eb_01krdgeqcxet5s7t44vh8rt9mg", previewParams)
if err != nil {
log.Fatal(err)
}
accepted, err := client.Broadcasts.Test(context.Background(), "eb_01krdgeqcxet5s7t44vh8rt9mg", bird.BroadcastsTestParams{BroadcastsPreviewParams: previewParams, To: "member@example.com", PreviewFingerprint: preview.PreviewFingerprint}, option.WithIdempotencyKey("broadcast-preview-intent-1"))
if err != nil {
log.Fatal(err)
}
fmt.Println(accepted.Id, *accepted.Status)$params = ['template' => ['parameters' => ['title' => 'Welcome', 'offer' => 'OCTOBER20', 'discount' => 20, 'featured' => false]], 'contact_id' => 'con_01krdgeqcxet5s7t44vh8rt9mg'];
$preview = $bird->broadcasts->preview('eb_01krdgeqcxet5s7t44vh8rt9mg', $params);
$accepted = $bird->broadcasts->test('eb_01krdgeqcxet5s7t44vh8rt9mg', $params + ['to' => 'member@example.com', 'preview_fingerprint' => $preview->getPreviewFingerprint()], new \MessageBird\RequestOptions(idempotencyKey: 'broadcast-preview-intent-1'));
echo $accepted->getId(), ' ', $accepted->getStatus();bird email broadcasts test <broadcast-id> \
--contact-id con_01krdgeqcxet5s7t44vh8rt9mg \
--from 'Jane Doe <jane@acme.com>' \
--header X-Campaign=spring-launch \
--preview-fingerprint fingerprint_from_matching_preview \
--to member@example.com \
--idempotency-key "${IDEMPOTENCY_KEY:?Set a fresh key for a new request; reuse it for retries}"curl -X POST "https://us1.platform.bird.com/v1/email/broadcasts/{broadcast_id}/test" \
-H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Jane Doe <jane@acme.com>",
"headers": {
"X-Campaign": "spring-launch"
},
"contact_id": "con_01krdgeqcxet5s7t44vh8rt9mg",
"to": "member@example.com",
"preview_fingerprint": "fingerprint_from_matching_preview"
}'{
"id": "em_01krdgeqcxet5s7t44vh8rt9mg",
"from": {
"email": "onboarding@messagebird.dev",
"name": "Bird"
},
"to": [
{
"email": "delivered@messagebird.dev"
}
],
"subject": "Hello from Bird",
"category": "marketing",
"status": "accepted",
"broadcast_id": "eb_01krdgeqcxet5s7t44vh8rt9mg",
"accepted_count": 1,
"processed_count": 0,
"delivered_count": 0,
"bounced_count": 0,
"complained_count": 0,
"deferred_count": 0,
"rejected_count": 0,
"open_count": 0,
"click_count": 0,
"track_opens": false,
"track_clicks": false,
"created_at": "2026-07-01T12:00:00Z"
}
Supply the same changes, contact and fingerprint as a new preview to send the exact rendered content to an authorized current organization member with workspace access. Requires template read and emails write permission. Alternate-member and machine destinations also require members read. A change to template content, envelope fields, parameters or contact values returns E04089 (BroadcastPreviewChanged), a conflict_error. This does not send the campaign audience. A confirmed response replays unchanged for the same key and request within the configured idempotency window, with fresh authorization and member access checks. A replay sends no other test.
Paramètres
broadcast_idstringBroadcast identifier.
Corps de la requête
templateReplaces the template, language or parameters for this request. Null removes the template for this request.
Afficher les paramètres enfants
template.idSelect this template. Changing the ID clears the old language, parameters and parameter overrides before supplied replacements. Repeating the same ID retains those values and clears the selected template version, so the next preparation uses the template's latest published version. Omit id to retain the selected template. Adding parameters to a draft created before parameters existed may clear its selected version so it uses the template's latest published version. To clear a draft's selection, set template itself to null.
template.languageThe BCP-47 language tag that goes to the whole audience, such as en or pt-BR. It must be an exact match for a language on the template's published version, so fr-CA does not select fr. Leave it out to keep the language already selected. If you change the template id in the same request, the old language is cleared with the old template. Set this to null to use the published version's default language, unless the template has language_source_required set.
template.parametersComplete template input map. Each value is a string, number, boolean or null and is used exactly as given, so text containing braces or code-like syntax is never evaluated. Objects and lists are not accepted. Use bird.contact.first_name in the template for contact data. Names must be bare input names outside the bird namespace. Omission retains the map unless the template ID changes, which clears it; an empty object clears it, and null is invalid. The compact map is limited to 16384 UTF-8 bytes and 128 names. Individual email parameters keep their own format.
template.parameter_overridesComplete map of per-language parameter values, keyed by a BCP-47 language tag of at most 35 characters such as es or pt-BR. Each language holds only the names whose value differs for that language; a name it leaves out uses the value in parameters, including later changes to it. A value that is present always applies, even when it is "", 0, false, null or equal to the parameters value. To return a name to the parameters value, send the map without it. Sending this map, even as {}, applies language rules to the broadcast: parameters must hold every input the default language's content, sender name, reply-to or headers use, and an input only the selected language uses may come from that language's entry instead. A broadcast that never sends it keeps the selected-language rules. Values for the default language, or for a language the broadcast does not send, are kept but not used. Omission retains the map unless the template ID changes, which clears it; an empty object removes every override, null is invalid and a language with no names is removed. Tags are stored in canonical BCP-47 form, so two spellings of one tag are refused. The compact map is limited to 16384 UTF-8 bytes, and parameters and every language together are limited to 128 distinct names.
fromReplaces the sender for this request. Give it as a plain address, as Jane <jane@acme.com> to include a display name, or as an object with an address and a name.
reply_toReplaces the reply-to addresses for this request. Null removes them.
headersReplaces the custom headers for this request rather than adding to them. Up to 25 of them, each value up to 998 characters. The header rules for updating a broadcast apply.
contact_idThe workspace contact whose values fill bird.contact. inputs. Required when the template or envelope reads contact data. Present values are used as they are, and a property's fallback applies only when the contact has no value for it.
toThe email address of a current organization member with access to this workspace.
preview_fingerprintThe preview_fingerprint returned by the preview whose content you are sending.
Contenu de la réponse
idMessage ID.
fromSender address. name is present when a display name was provided on the send.
toPrimary recipients. Length is the recipient count. Use the broadcasts endpoint for audience-targeted sends. Each entry's name is present when a display name was provided on the send.
subjectThe subject line as delivered. For a send that used a template, the stored subject is the template's, so this reports it with the send's parameters substituted in, which is what the recipient saw.
categoryContent classification, which controls suppression policy:
marketing: Blocks on all suppression reasons.transactional: Allows delivery through complaint and unsubscribe suppressions, for receipts, password resets, and similar operational mail.
Possible values: marketing, transactional
reply_toReply-To addresses, if set on the send. Empty/null when no Reply-To was provided.
statusaccepted_countHow many recipients are in the accepted state, meaning we have the message and are getting ready to deliver it.
processed_countHow many recipients the message has been prepared for and queued for delivery.
delivered_countHow many recipients' messages were accepted by their mail server.
bounced_countNumber of recipients that resulted in a permanent delivery failure.
complained_countNumber of recipients that reported spam.
deferred_countNumber of recipients in transient delivery deferral. Their mail server asked for a retry, and delivery attempts continue.
rejected_countNumber of recipients rejected before delivery. Read the per-recipient rejection_reason field on GET /v1/email/messages/{message_id}/recipients for the specific cause.
processing_latency_msTime between the send being accepted and the message being prepared for delivery, in milliseconds, for the fastest recipient. Null until the first recipient reaches processed.
delivery_latency_msTime between the message being processed and the receiving mail server accepting it, in milliseconds, for the fastest delivered recipient. Null until the first recipient is delivered.
total_latency_msEnd-to-end accept → delivered time for the fastest delivered recipient, in milliseconds. Null until the first recipient is delivered.
open_countTotal open events across all recipients.
click_countTotal click events across all recipients.
requested_languageThe template language this send asked for, in canonical form (pt-BR for a request of pt-br). Null when the send named no language (it took the template's default) or used no template at all. Compare it with resolved_language: when they differ, the language you asked for was not available and the template's on_missing_language policy chose the one shown there instead.
resolved_languageThe template language this send was actually delivered in, in canonical form. Null when the send used no template. A non-null value with a null requested_language means the send named no language and took the template's default.
template_idThe template this send rendered from, or null for a send that supplied its content inline.
template_version_idThe exact template version this send rendered from, or null for an inline send. A template's live version changes every time you submit it, so this is what identifies the wording that was actually delivered, together with resolved_language.
broadcast_idThe broadcast that sent this message. Absent for a send that was not part of a broadcast. A broadcast records one message per recipient, and every one of them carries the same value here.
tagsLabels on this message, each one a name and a value, that you can filter and search messages by. Use tags for anything you want to find messages by later, and metadata for data you only want handed back to you.
metadataAny JSON you kept on the message. We store it and hand it back in webhook payloads, and that is all it does. If you want to search or filter by it, use tags instead.
parametersThe substitution values this send supplied, whether inline or from a template, or null if none were supplied. They are the values applied to subject and to the bodies the content endpoint returns, kept so you can see what produced the delivered copy and not only the result.
attachmentsAttachment metadata for the send. Empty when no attachments were included. Raw content is not echoed. When content storage is enabled, download an attachment by its id via the message's attachment endpoint.
track_opensWhether open tracking is enabled for this send.
track_clicksWhether click tracking is enabled for this send.
created_atWhen the send request was accepted.
thread_idThread this message belongs to, or null when the message is not part of one.
in_reply_to_message_idThe message this one is a reply to, if any.
delivered_atWhen all recipients reached a terminal delivered state, or null if not yet fully delivered.
scheduled_atWhen this message is scheduled to send, for a send created with a future send time. Absent for an immediate send. Stays set after the scheduled send fires.
Ressources associées
Poursuivez avec la documentation, les guides et les exemples sur ce sujet.