POST /v1/actions/trigger-sequence

Start a published sequence for a contact. Returns the sequence session id, or `already_running` if the contact is already in it.

Enrolls a contact in a published sequence. Sequences are multi-step time-spaced campaigns — typically a "welcome" or "drip" series with delays between steps.

If the contact already has a running session for this sequence, the endpoint returns 200 with status: "already_running" and does not start a second one. This makes the call safe to retry.

POST /api/v1/actions/trigger-sequence

Request body

Field Type Required Notes
sequence_id UUID yes Must be a published sequence (published_at not null)
contact_id UUID one of Lookup existing contact
phone string one of Lookup or create contact (auto-upsert with opted_in_at: now)
context object no Free-form key/value bag passed to every node in the sequence
curl -X POST https://www.qyvo.io/api/v1/actions/trigger-sequence \
  -H "Authorization: Bearer YOUR_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "sequence_id": "01J3S...",
    "phone": "+14155550123",
    "context": { "order_id": "ORD-1042", "first_name": "Romain" }
  }'
const session = await fetch('https://www.qyvo.io/api/v1/actions/trigger-sequence', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.QYVO_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    sequence_id: '01J3S...',
    phone: '+14155550123',
    context: { order_id: 'ORD-1042', first_name: 'Romain' },
  }),
}).then((r) => r.json());
$session = Http::withToken(env('QYVO_TOKEN'))
    ->post('https://www.qyvo.io/api/v1/actions/trigger-sequence', [
        'sequence_id' => '01J3S...',
        'phone' => '+14155550123',
        'context' => ['order_id' => 'ORD-1042', 'first_name' => 'Romain'],
    ])
    ->json();
import os, httpx
session = httpx.post(
    'https://www.qyvo.io/api/v1/actions/trigger-sequence',
    headers={'Authorization': f"Bearer {os.environ['QYVO_TOKEN']}"},
    json={
        'sequence_id': '01J3S...',
        'phone': '+14155550123',
        'context': {'order_id': 'ORD-1042', 'first_name': 'Romain'},
    },
).json()

Response — 201 Created

{
  "id": "01J5B...",
  "status": "started",
  "sequence_id": "01J3S...",
  "sequence_name": "Welcome 7-day",
  "contact_id": "01J1Y..."
}

If the contact is already in the sequence:

{
  "id": "01J5B...",
  "status": "already_running",
  "message": "Contact is already in this sequence"
}

Errors

Status Cause
404 Sequence not found or not published — publish it first in the dashboard
404 Contact not found (only when looking up by contact_id)
422 Sequence has no entry node — the sequence graph is empty; edit it in the dashboard
422 Neither contact_id nor phone provided

Context usage

Anything you pass in context is available to template-message nodes inside the sequence as {{context.first_name}}, {{context.order_id}}, etc. Useful for personalizing the campaign with order or product data.