# Setting up event-triggers

## Yazi API

The Yazi API lets you programmatically send WhatsApp template messages and access your research data. You can trigger on-demand messages to individual phone numbers, broadcast to study participants, and pull study results -- all via simple REST endpoints.

**Base URL:** `https://api.askyazi.com/v1`

***

### Authentication

All requests require an API key sent as a header:

```
x-api-key: your-api-key-here
```

{% hint style="warning" %} The header name must be exactly `x-api-key` (all lowercase). It is case-sensitive. {% endhint %}

Your API key is provided by the Yazi team. Include it on every request.

**Example:**

```bash
curl -H "x-api-key: your-api-key" https://api.askyazi.com/v1/study
```

Contact the Yazi team if you need your API key or have any questions about the integration.

***

### Quick reference

| Action                          | Method | Endpoint                              |
| ------------------------------- | ------ | ------------------------------------- |
| List event schedules            | `GET`  | `/v1/jobs/schedule`                   |
| Create event schedule           | `POST` | `/v1/jobs/schedule`                   |
| Update event schedule           | `PUT`  | `/v1/jobs/schedule/{configurationId}` |
| Trigger schedule (send message) | `POST` | `/v1/jobs`                            |
| Send broadcast                  | `POST` | `/v1/study/{studyId}/broadcast`       |
| List studies                    | `GET`  | `/v1/study`                           |
| Study details                   | `GET`  | `/v1/study/{studyId}`                 |
| Study results                   | `GET`  | `/v1/study/{studyId}/results`         |
| Study participants              | `GET`  | `/v1/study/{studyId}/participants`    |

***

### Event-triggered schedules

Event-triggered schedules let your system send a WhatsApp template message to a single phone number on demand. You set up a schedule configuration once (choosing the template, variables, and buttons), then trigger it whenever you need to send a message.

**Typical use case:** Your CRM fires a webhook when a new lead signs up. That webhook calls the trigger endpoint with the lead's phone number and name, and a personalised WhatsApp message goes out instantly.

```
┌─────────────┐     POST /v1/jobs     ┌───────────────┐     WhatsApp API     ┌──────────┐
│  Your System │ ──────────────────> │  Yazi Platform │ ──────────────────> │ Recipient │
│  (CRM, App)  │  phone + variables  │               │  Template message    │          │
└─────────────┘                      └───────────────┘                      └──────────┘
```

**You have two options:**

* **Option A:** Create the schedule yourself via API, then trigger it.
* **Option B:** Ask the Yazi team to create the schedule for you -- then you only need to call the trigger endpoint.

***

#### List event schedules

Returns all event-triggered schedule configurations for your organisation. Use this to find your `configurationId` if you don't have it.

```
GET /v1/jobs/schedule
```

**Example:**

```bash
curl -H "x-api-key: your-api-key" \
  https://api.askyazi.com/v1/jobs/schedule
```

***

#### Create a schedule

Define which WhatsApp template to send and what variables it expects. You create it once, then trigger it as many times as you need.

```
POST /v1/jobs/schedule
```

**Headers:**

```
Content-Type: application/json
x-api-key: your-api-key
```

**Body:**

```json
{
  "name": "Welcome Message",
  "description": "Send a welcome message to new users",
  "template_name": "welcome_v1",
  "message_variables": ["first_name"]
}
```

| Field               | Type      | Required | Description                                                   |
| ------------------- | --------- | -------- | ------------------------------------------------------------- |
| `name`              | string    | Yes      | A name for this schedule (for your reference)                 |
| `description`       | string    | No       | A description of what this schedule does                      |
| `template_name`     | string    | Yes      | The exact WhatsApp template name (must exist and be approved) |
| `message_variables` | string\[] | No       | Variable names your template uses, in order                   |
| `buttons`           | object\[] | No       | Button definitions (see Advanced sections below)              |
| `language`          | string    | No       | Template language code (default: `en_US`)                     |
| `status`            | string    | No       | `ACTIVE` or `INACTIVE` (default: `ACTIVE`)                    |

**Response (201):**

```json
{
  "success": true,
  "message": "Schedule configuration created",
  "data": {
    "id": "abc12345-def6-7890-abcd-ef1234567890",
    "name": "Welcome Message",
    "description": "Send a welcome message to new users",
    "templateName": "welcome_v1",
    "organisationId": "org-uuid-here",
    "messageVariables": ["first_name"],
    "buttons": [],
    "type": "event_triggered",
    "status": "ACTIVE",
    "createdAt": "2025-01-15T10:00:00.000Z"
  }
}
```

Save the returned `id`. This is your `configurationId` that you will use to trigger messages.

{% hint style="info" %} **Template validation:** The `template_name` must match an approved WhatsApp template in your organisation. If the template doesn't exist, the API returns an error with a list of your available templates. If the template exists but isn't approved yet (e.g. still PENDING in Meta), the API will tell you the current status. {% endhint %}

***

#### Update a schedule

Update any field of a schedule. Send only the fields you want to change. All fields are optional.

```
PUT /v1/jobs/schedule/{configurationId}
```

| Field               | Type      | Description                                         |
| ------------------- | --------- | --------------------------------------------------- |
| `name`              | string    | Schedule name                                       |
| `description`       | string    | Schedule description                                |
| `template_name`     | string    | WhatsApp template name (must exist and be approved) |
| `message_variables` | string\[] | Variable names for the template                     |
| `buttons`           | object\[] | Button definitions                                  |
| `language`          | string    | Template language code                              |
| `status`            | string    | `ACTIVE` or `INACTIVE`                              |

**Example: deactivate a schedule**

```json
{
  "status": "INACTIVE"
}
```

**Example: change the template**

```json
{
  "template_name": "welcome_v2",
  "message_variables": ["first_name", "last_name"]
}
```

{% hint style="info" %} If you change the `template_name`, the same validation applies. The template must exist and be approved, or you'll get an error with the list of available templates. {% endhint %}

***

#### Trigger a schedule (send a message)

Send a WhatsApp template message to a single phone number.

```
POST /v1/jobs
```

**Headers:**

```
Content-Type: application/json
x-api-key: your-api-key
```

**Body:**

```json
{
  "configurationId": "abc12345-def6-7890-abcd-ef1234567890",
  "phoneNumber": "+27821234567",
  "variables": {
    "Name": "Thabo Mokoena",
    "Topic": "Customer Satisfaction Survey"
  }
}
```

| Field             | Type   | Required | Description                                                     |
| ----------------- | ------ | -------- | --------------------------------------------------------------- |
| `configurationId` | UUID   | Yes      | The schedule configuration ID                                   |
| `phoneNumber`     | string | Yes      | Recipient phone in E.164 format (e.g. `+27821234567`)           |
| `variables`       | object | Depends  | Key-value pairs matching the parameter names from your template |

**Response (202):**

```json
{
  "status": "success",
  "data": {
    "jobId": "request-id",
    "type": "EVENT_TRIGGERED",
    "status": "ACCEPTED",
    "message": "Job has been accepted for processing."
  }
}
```

{% hint style="info" %} **Don't want to create the schedule yourself?** The Yazi team can set it up for you. Just tell us which WhatsApp template to use, what variable names the template needs, and whether buttons should link to a campaign or URL. We'll give you a `configurationId` and you just call `POST /v1/jobs`. {% endhint %}

***

### Variables: how they work

Variables are the dynamic parts of your WhatsApp template. For example, if your template says:

> Hi {{1}}, we are conducting research on {{2}}. Press Start to begin.

And the template has parameters defined as `["Name", "Topic"]`, then:

**When creating the schedule:**

```json
"message_variables": ["Name", "Topic"]
```

**When triggering, use the exact parameter names:**

```json
"variables": {
  "Name": "Thabo Mokoena",
  "Topic": "Customer Satisfaction"
}
```

The result: *"Hi Thabo Mokoena, we are conducting research on Customer Satisfaction. Press Start to begin."*

**Key points:**

* Variable names must exactly match the parameter names defined in your WhatsApp template.
* Variables are a simple flat object -- just `"name": "value"` pairs.
* The order is handled automatically based on the `message_variables` array.
* If you're missing a required variable, the API will tell you exactly which ones are needed.

***

### Advanced: templates with URL buttons

If your template has a button that links to a URL with a dynamic part (e.g. a survey link), you can include button variables.

**Creating the schedule:**

```json
{
  "name": "Survey Invite",
  "template_name": "survey_invite_v2",
  "message_variables": ["first_name"],
  "buttons": [
    {
      "type": "url",
      "text": "Start Survey",
      "url": "https://app.example.com/survey/{{survey_id}}",
      "variables": ["survey_id"]
    }
  ]
}
```

**Triggering: all variables go in one flat object**

```json
{
  "configurationId": "your-config-id",
  "phoneNumber": "+27821234567",
  "variables": {
    "first_name": "Thabo",
    "survey_id": "abc-123"
  }
}
```

You don't need to separate message variables from button variables. Put everything in `variables` and the service handles the rest.

***

### Advanced: templates with quick reply buttons

Quick reply buttons let the recipient tap a button to start a campaign or opt out.

**Creating the schedule:**

```json
{
  "name": "Campaign Invite",
  "template_name": "campaign_invite_v1",
  "message_variables": ["first_name"],
  "buttons": [
    {
      "type": "quick_reply",
      "text": "Start",
      "campaignId": "your-campaign-uuid"
    },
    {
      "type": "quick_reply",
      "text": "Opt-out"
    }
  ]
}
```

***

### Send broadcast

Send a WhatsApp template message to all (or filtered) participants of a study.

```
POST /v1/study/{studyId}/broadcast
```

**Headers:**

```
Content-Type: application/json
x-api-key: your-api-key
```

**Body:**

```json
{
  "templateName": "follow_up_reminder",
  "variables": {
    "first_name": "Thabo"
  },
  "filterByActivity": "activity-uuid",
  "filterByStatus": "active"
}
```

| Field              | Type   | Required | Description                                                                  |
| ------------------ | ------ | -------- | ---------------------------------------------------------------------------- |
| `templateName`     | string | Yes      | The WhatsApp template name to send                                           |
| `variables`        | object | No       | Key-value pairs for template variables                                       |
| `filterByActivity` | UUID   | No       | Only send to participants in this activity                                   |
| `filterByStatus`   | string | No       | Filter by participant status: `active`, `completed`, `dropped_out`, `paused` |

***

### Error handling

All errors return a JSON body with details about what went wrong.

#### Template not found

If the `template_name` you provide doesn't exist for your organisation:

```json
{
  "success": false,
  "error": "Template \"nonexistent_template\" not found for this organisation",
  "details": {
    "providedTemplate": "nonexistent_template",
    "availableTemplates": [
      "welcome_v1",
      "survey_invite_v2",
      "campaign_invite_v1"
    ]
  }
}
```

The `availableTemplates` list shows all approved templates you can use.

#### Template not approved

If the template exists but hasn't been approved by Meta yet:

```json
{
  "success": false,
  "error": "Template \"pending_template\" is not approved (current status: PENDING)",
  "details": {
    "templateName": "pending_template",
    "templateStatus": "PENDING",
    "hint": "Only templates with status APPROVED can be used. Check your Meta Business Manager."
  }
}
```

#### Missing variables

If required template variables are not included when triggering a schedule:

```json
{
  "status": "error",
  "error": {
    "code": "INVALID_CONFIGURATION",
    "message": "Invalid job configuration.",
    "requestId": "request-uuid",
    "details": {
      "missingVariables": ["Name", "Topic"],
      "example": {
        "Name": "<value>",
        "Topic": "<value>"
      }
    }
  }
}
```

#### Validation error

```json
{
  "status": "error",
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "phoneNumber: Must be E.164 format (e.g. +27821234567)"
  }
}
```

#### Schedule configuration not found

```json
{
  "status": "error",
  "error": {
    "code": "CONFIGURATION_NOT_FOUND",
    "message": "Schedule configuration not found"
  }
}
```

#### Invalid or missing API key

**Missing (401):**

```json
{
  "status": "error",
  "error": {
    "code": "MISSING_API_KEY",
    "message": "An x-api-key header is required. Include your API key in the request.",
    "requestId": "request-uuid"
  }
}
```

**Invalid (401):**

```json
{
  "status": "error",
  "error": {
    "code": "INVALID_API_KEY",
    "message": "The provided API key is not valid.",
    "requestId": "request-uuid"
  }
}
```

#### Status codes

| Status | Meaning                                            |
| ------ | -------------------------------------------------- |
| 200    | Success                                            |
| 201    | Created successfully                               |
| 202    | Accepted for processing                            |
| 400    | Bad request -- check the error message for details |
| 401    | Missing or invalid API key                         |
| 404    | Resource not found (study, schedule, etc.)         |
| 429    | Rate limit exceeded -- wait and retry              |
| 500    | Server error -- contact Yazi support               |

***

### Postman collection

A ready-to-import Postman collection is available. To get started:

1. Open **Postman**
2. Click **Import** and select the `postman-collection.json` file
3. Click the collection name, go to the **Variables** tab
4. Fill in:
   * `baseUrl` -- the API URL (provided by the Yazi team)
   * `apiKey` -- your API key
   * `studyId` -- a study ID (use the List Studies endpoint to find one)
   * `configurationId` -- a schedule ID (after creating one, or provided by the Yazi team)
5. Save and start testing

***

### Need help?

Contact the Yazi team if you need:

* Your API key
* Help choosing or creating a WhatsApp template
* A schedule configuration set up for you
* Access to additional endpoints
* Any questions about the integration
