Send listings to Halo

Post events, places or offerings from your own system to a webhook source in Halo CRM. The token, the body, how repeats are handled, and what comes back.

A webhook source lets your own system post to Halo CRM's directory: a ticketing system's events, say. What you post goes to the Inbox for someone to decide on, or applies itself if the source is trusted.

Make a source

In Halo CRM, under Sources, choose New source, and under What to read pick Something that posts to Halo. It takes someone who can manage the CRM.

  • The token starts with hci_ and shows once. It does this one thing and nothing else. Choose New token there if it leaks.

  • What it finds says what your items are, such as events. A sender can't set an item's kind, status or business: those are for people at your organization.

  • Trust this source applies what you send, unless it might be a duplicate, lacks something its kind needs, or would take the directory past your plan. Those wait in the Inbox, as everything does from a source you don't trust.

  • The key holding each item's id names your own id key, if it isn't id.

  • Which key fills which field names your own keys, if they aren't the fields below. name from title, for example. With any set, only the keys you name are read.

Post to it

curl -sS -X POST https://api.usehalo.net/v1/public/crm/ingest \
  -H "Authorization: Bearer $HALO_INGEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {
        "id": "evt-2041",
        "name": "Oyster Night",
        "summary": "Shucking lessons on the pier.",
        "website": "https://example.com/oyster-night",
        "city": "Newport",
        "startsAt": "2026-12-12T18:00:00-08:00",
        "tags": ["food"]
      }
    ]
  }'

The body is one item, a list of them, or an object with items. Up to 2,000 items and 4 MB a request.

FieldMeans
idYour own id for it, or the key the source names instead. Send one: it's how Halo tells a change from something new. Without it, the fields themselves are the key, so any edit looks new
nameIts name
summary, descriptionA line about it, and more
website, email, phoneHow to reach it, as a reader would
address, city, postalCodeWhere it is
regionA region's key, from the directory's settings. Left out, the source's Region, or else one worked out from the postal code or lat and lng
lat, lngWhere it is, in numbers
startsAt, endsAtFor a happening, as ISO 8601. A date with no zone reads in your organization's time zone
tagsA list of words
dataThe fields the kind adds, by their keys

Anything else is ignored. Send only what you know: an item doesn't clear what's already there.

What comes back

{ "found": 1, "new": 1, "updated": 0, "unchanged": 0, "applied": 0, "dropped": 0 }
FieldMeans
foundItems read. Each is counted in exactly one of new, updated, unchanged, applied and dropped, so they add up to it
newThings Halo hadn't seen, now waiting in the Inbox
updatedChanges to what it had, now waiting in the Inbox
unchangedItems that said what they said last time
appliedNew things and changes that applied themselves, for a trusted source. They aren't in new or updated too
droppedItems left out, such as one with nothing usable
skippedHow many values couldn't be used, by field, such as { "startsAt": 1 } for a date nobody can read, or a region you don't have. The rest of each item still arrives. Left out when there are none

Sending the same item twice changes nothing, so it's safe to retry and safe to send everything each night.

When it's refused

AnswerMeans
401 invalid_tokenThe token is wrong or was rolled, or the organization is suspended, deleted or doesn't have Halo CRM. It doesn't say which
400 bad_requestThe body isn't JSON
422 validation_failedThe body is neither an object nor a list, or has more than 2,000 items
429 rate_limitedToo many posts from your address: 120 a minute. Wait, then send again

This route isn't part of the Developer API. It takes a source's token, and an API key gets 401. To read the directory back, use the Developer API.