Send transactional push
Send a one-off push notification to a user. Unlike most API-key routes, this one IS workspace-scoped, and the workspace in the path must match the one the API key belongs to. Requires push:send (never grantable on a public key).
The workspace send policy applies: quiet hours, the daily cap (max_pushes_per_day) and the rolling-window cap (max_pushes_per_window per window_hours) each return 200 with status: policy_suppressed rather than an error — an order confirmation can be silently held by quiet hours, so check status, not just the HTTP code.
curl -X POST "https://api.flameup.ai/api/v1/workspaces/example_string/push/send" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-d '{
"external_id": "example_string",
"title": "example_string",
"body": "example_string",
"image_url": "example_string",
"action_url": "example_string",
"custom_data": {},
"variables": {},
"event_id": "example_string",
"campaign_id": "example_string",
"scheduled_at": "2024-12-25T10:00:00Z",
"tags": [
"example_string"
]
}'
import requests
import json
url = "https://api.flameup.ai/api/v1/workspaces/example_string/push/send"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
}
data = {
"external_id": "example_string",
"title": "example_string",
"body": "example_string",
"image_url": "example_string",
"action_url": "example_string",
"custom_data": {},
"variables": {},
"event_id": "example_string",
"campaign_id": "example_string",
"scheduled_at": "2024-12-25T10:00:00Z",
"tags": [
"example_string"
]
}
response = requests.post(url, headers=headers, json=data)
print(response.json())
const response = await fetch("https://api.flameup.ai/api/v1/workspaces/example_string/push/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
},
body: JSON.stringify({
"external_id": "example_string",
"title": "example_string",
"body": "example_string",
"image_url": "example_string",
"action_url": "example_string",
"custom_data": {},
"variables": {},
"event_id": "example_string",
"campaign_id": "example_string",
"scheduled_at": "2024-12-25T10:00:00Z",
"tags": [
"example_string"
]
})
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"net/http"
"bytes"
"encoding/json"
)
func main() {
data := []byte(`{
"external_id": "example_string",
"title": "example_string",
"body": "example_string",
"image_url": "example_string",
"action_url": "example_string",
"custom_data": {},
"variables": {},
"event_id": "example_string",
"campaign_id": "example_string",
"scheduled_at": "2024-12-25T10:00:00Z",
"tags": [
"example_string"
]
}`)
req, err := http.NewRequest("POST", "https://api.flameup.ai/api/v1/workspaces/example_string/push/send", bytes.NewBuffer(data))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer YOUR_API_TOKEN")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("Response Status:", resp.Status)
}
require 'net/http'
require 'json'
uri = URI('https://api.flameup.ai/api/v1/workspaces/example_string/push/send')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer YOUR_API_TOKEN'
request.body = '{
"external_id": "example_string",
"title": "example_string",
"body": "example_string",
"image_url": "example_string",
"action_url": "example_string",
"custom_data": {},
"variables": {},
"event_id": "example_string",
"campaign_id": "example_string",
"scheduled_at": "2024-12-25T10:00:00Z",
"tags": [
"example_string"
]
}'
response = http.request(request)
puts response.body
{
"message_id": "9f2c1e77-4a1b-4c2e-9a0f-51a6b2d3c8e4",
"status": "sent",
"sent_at": "2024-12-25T10:00:00Z",
"provider": "fcm",
"provider_id": "example_string",
"error": "example_string",
"skip_reason": "no_active_device_tokens"
}
{
"success": false,
"error": "Person not found",
"code": "example_string"
}
{
"error": "Unauthorized",
"message": "Invalid or expired API key",
"details": "Please provide a valid API key in the Authorization header: Bearer <your_api_key>"
}
{
"success": false,
"error": {
"code": "example_string",
"message": "example_string",
"details": {}
}
}
{
"success": false,
"error": "Person not found",
"code": "example_string"
}
{
"error": "Unauthorized",
"message": "Invalid or expired API key",
"details": "Please provide a valid API key in the Authorization header: Bearer <your_api_key>"
}
{
"success": false,
"error": {
"code": "example_string",
"message": "example_string",
"details": {}
}
}
{
"success": false,
"error": "Person not found",
"code": "example_string"
}
{
"error": "Unauthorized",
"message": "Invalid or expired API key",
"details": "Please provide a valid API key in the Authorization header: Bearer <your_api_key>"
}
{
"success": false,
"error": {
"code": "example_string",
"message": "example_string",
"details": {}
}
}
{
"success": false,
"error": "Person not found",
"code": "example_string"
}
{
"error": "Unauthorized",
"message": "Invalid or expired API key",
"details": "Please provide a valid API key in the Authorization header: Bearer <your_api_key>"
}
{
"success": false,
"error": {
"code": "example_string",
"message": "example_string",
"details": {}
}
}
/workspaces/{workspaceId}/push/sendTarget server for requests. Edit to use your own host.
Your Flameup API key (passed as Bearer token)
Workspace ID
The media type of the request body
Your own user id — the same one you send to /identify and /track. The Flameup person UUID is not accepted.
Rides the FCM message payload verbatim (reserved FCM keys are stripped). String values render through the same template pipeline as title/body.
Template variables for rendering title/body/custom_data.
Optional event id to attribute this send to.
Optional campaign id to attribute this send to.
Schedule the send for a future time.
Request Preview
Response
Response will appear here after sending the request
Authentication
Bearer token. Your Flameup API key (passed as Bearer token)
Path Parameters
Workspace ID
Body
Your own user id — the same one you send to /identify and /track. The Flameup person UUID is not accepted.
Rides the FCM message payload verbatim (reserved FCM keys are stripped). String values render through the same template pipeline as title/body.
Template variables for rendering title/body/custom_data.
Optional event id to attribute this send to.
Optional campaign id to attribute this send to.
Schedule the send for a future time.
Responses
Use with the push status route. For skipped results this is a synthetic skipped-\<unix\> value; policy_suppressed results reference a real (suppressed) record.
sent — handed to the provider (not proof of delivery). skipped — nothing was sent and nothing is retried: the person has no active device tokens, the requested token is not one of their active devices, or the token is suppressed; the reason is in error. policy_suppressed — the workspace send policy (quiet hours, daily cap, or the rolling-window cap) blocked the send. failed — batch responses only; the single-send route reports provider failures as HTTP 500 instead.
sentskippedpolicy_suppressedfailedfcm, or none for skipped results.
The provider's own message identifier.
Present on non-sent results — the skip or suppression reason, or the failure message. Prose for a human; branch on skip_reason instead.
The authoritative "nothing was delivered" signal. Present — and present only — when the send did not reach the provider, so its presence rather than the status string is what to branch on: a future provider status (queued, throttled, …) is never mistaken for a skip. The tokens are stable and machine-readable, unlike the prose in error.
person_unsubscribedperson_suppressedno_active_device_tokensrequested_device_not_activedevice_token_suppressedquiet_hoursfrequency_caprolling_cap