UtilitayDevelopers
Ravenraven
Get an API key
Guides

Quickstart

Six calls from key to delivered message. The paths and field names never change; the nouns and bodies come from the pack. Switch packs to see the same six calls in another vertical, or compare two side by side.

Shown inSubscription businesssubscription_businesscompared with
Run it in Postman

Every endpoint, in the Subscription business pack’s words, with a Record an event request for each of its 13 event types. Bodies come from the pack’s schemas, each response is validated against its JSON Schema, and the requests run in order: a create saves its id for the ones after it.

Download collection
  1. 01

    Get a key

    Utilitay Account

    Open your organisation in Utilitay Account, then the Developers tab. Create a Raven key with contacts:write, subjects:write, events:write and messages:read, reaching the instance you will call. The key is shown once; send it as a bearer token on every request.

    Headeron every request
    Authorization: Bearer utl_live_k3Jh9QpL2mZx7VbN4cRt8WyS1dFg6HaU0eIo5PqA3zK1a2B3c
    utl_live_ prefix · 43-character body · 6-character checksum. Roll or revoke it in the same tab.
  2. 02

    Create a subject

    subjects:write

    The subject is what events are about. The fixed fields are display_name and external_ref; everything inside attributes comes from the pack schema, and unknown keys are refused.

    SubscriptionsubjectPOST/subjects
    {
      "display_name": "Raven Tier 2",
      "external_ref": "SUB-2026-001",
      "attributes": {
        "plan": "Example",
        "region": "Example",
        "status": "Trial",
        "product": "Example",
        "billing_cycle": "Monthly"
      }
    }
  3. 03

    Create a contact

    contacts:write

    The contact is the person who receives messages. A name and a phone number in E.164 are enough; WhatsApp or SMS is chosen per message by your rules. Where an instance takes contacts with no phone number, an email address and your own reference stand in its place.

    CustomercontactPOST/contacts
    {
      "name": "Hawa Kollie",
      "email": "hawa.kollie@example.com",
      "external_ref": "CON-1042",
      "channel_pref": "email",
      "attributes": {
        "company": "Example",
        "timezone": "Example",
        "job_title": "Example"
      }
    }
    Instances of this pack start out taking customers with no phone number: the address is how they are reached, the reference is the only exact key they have, and the preferred channel can only be email.
  4. 05

    Record an event

    events:write

    This is the call that makes Raven send. It validates the payload against the type, dedupes on your reference and the type’s dedupe fields, judges it against your rules, and queues the messages. The response tells you what fired.

    Incident= incidentPOST/events
    {
      "type_key": "incident",
      "event_ref": "incident-2026-09-14",
      "payload": {
        "ref": "Example",
        "title": "Company notice",
        "detail": "Example",
        "status": "Example",
        "status_url": "Example"
      }
    }
    201 · one fire per rule judged · sends: how many messages that made
  5. 06

    Read the message

    messages:read

    Messages are read only. Each carries the channel, the body as it went and a delivery status that moves as WhatsApp and SMS report back.

    GET/messages?subject_id=8a3f5d21…
    Returns a bare array. Status: queued → sending → sent → delivered → read.
What stayed the same
/subjects · /contacts · /links
/events · /messages
subject_id · contact_id · type_key
What the pack decided
The nouns in the prose
Every key inside attributes and payload
Whether relationship is required
Whether a new instance starts out taking customers with no phone_e164