Heroshhi API reference

The same REST API the Heroshhi app uses: leads, messages, WhatsApp, drips and broadcasts. Log in to get a token, then send it with each request.

Base URLhttps://api.heroshhi.com/api

Authentication

Log in once to get a token, then include it in the header of every request. It proves who you are, like a session key.

Every request: Authorization: Bearer <token>

// Log in to receive a token
POST https://api.heroshhi.com/api/auth/login
Content-Type: application/json

{
  "email": "admin@yourcompany.com",
  "password": "your_password"
}

// Reply
{
  "success": true,
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Rate limits

To keep things fair, there's a limit on requests in a short time. Go over it, and you get 429 Too Many Requests: wait a moment and try again.

Kind of endpointRequestsPer
Standard API10015 minutes
Webhooks50015 minutes
Logging in515 minutes

Auth

/api/auth

MethodEndpointWhat it does
POST/loginLog in with email and password
POST/signupCreate an account
POST/forgot-passwordAsk for a password reset
POST/reset-passwordSet a new password with the reset token
POST/verify-2faCheck a two-step code
GET/meThe logged-in user

Leads

/api/leads

MethodEndpointWhat it does
GET/List leads, with filters (including stage) and pages
GET/:idOne lead, in full
POST/Create a lead
PUT/:idUpdate a lead
DEL/:idDelete a lead
POST/importImport leads in bulk (mode: fresh or history)
POST/bulk-updateUpdate several leads
POST/bulk-assignAssign several leads
POST/bulk-deleteDelete several leads
GET/analyticsLead numbers for reports
POST/:id/engagementRecord an engagement

Messages

/api/messages

MethodEndpointWhat it does
GET/List messages, with filters
GET/:leadIdMessages with one lead
POST/sendSend a message to a lead
GET/templatesYour WhatsApp templates

WhatsApp

/api/whatsapp

MethodEndpointWhat it does
GET/statusWhatsApp connection status
POST/connectConnect your WhatsApp Business API
DEL/disconnectDisconnect WhatsApp
POST/sendSend a message (refused if the contact opted out)
POST/send-bulkSend in bulk (opted-out contacts left out)
GET/coexistenceCoexistence settings
PUT/coexistenceChange coexistence settings

Drips and broadcasts

MethodEndpointWhat it does
GET/api/dripsList drip sequences
POST/api/drips/:id/enrollAdd leads to a sequence
POST/api/broadcastsCreate and send a broadcast
GET/api/broadcasts/:idOne broadcast, with results

Lead and message

Lead

FieldTypeMeaning
nameString, requiredThe lead's full name
phoneString, requiredPhone number with country code
stageEnumnew / contacted / qualified / converted / not_qualified / lost. Set by Heroshhi from what happened; read it, don't write it
stageAtDateWhen the lead reached its stage
statusEnumpending / contacted / qualified / converted / lost (older field, kept for compatibility)
segmentEnumhot / warm / cold: the team's own judgement
assignedToObjectIdThe team member who owns the lead
isOptedOutBooleanWhether the contact has opted out of messages

Message

FieldTypeMeaning
leadIdObjectIdThe lead
directionEnuminbound / outbound
statusEnumqueued / sent / delivered / read / failed

Lead webhook

Send leads into Heroshhi from any other system, such as your website or a form builder. No login needed: post the details, and the lead appears in your account.

POST /api/webhook/lead

{
  "name":    "John Doe",
  "phone":   "919876543210",
  "email":   "john.doe@example.com",
  "source":  "Website form",
  "inquiry": "Product enquiry",
  "userId":  "your_account_id"
}

Meta Conversions API

Meta knows a person clicked your ad. It doesn't know whether they became a customer. Heroshhi sends that back, so Meta can aim your ads at people who actually convert, not just people who fill in forms.

Three kinds of lead, three ways of sending

Meta identifies each source differently. With the wrong identifier, an event is accepted but never matched to an ad, so Heroshhi detects the source and sends it the right way.

Lead came fromIdentifieraction_sourceSent to
Website formfbclidwebsitePixel
Click-to-WhatsApp adctwa_clidbusiness_messagingPixel
Meta Instant Formlead_idsystem_generatedCRM dataset

Click-to-WhatsApp identifiers come in the referral object of the customer's first message, and are picked up automatically. Instant Form leads carry a 15 to 17 digit lead ID in the id column of Meta's export.

Events Heroshhi sends

EventSent when
LeadA new lead arrives, from any source
QualifiedThe lead shows real interest: a call logged as interested or a callback, or an appointment booked
ConvertedThe lead becomes a customer, with the value when a payment is recorded
Not QualifiedNever a real prospect: wrong number, spam, or a clear no before any interest
LostA real prospect who didn't buy, for example on price or because they booked elsewhere

Each event's name can be changed in your settings, to match the stages you set up in Meta's lead funnel.

Settings

PUT /api/users/conversion-api

{
  "facebook": {
    "enabled":       true,
    "pixelId":       "123456789012345",
    "accessToken":   "EAAxxxxx...",
    "crmDatasetId":  "987654321098765",
    "testEventCode": "TEST12345"
  },
  "events": {
    "sendLeadEvent":       true,
    "sendQualifiedEvent":  true,
    "sendConversionEvent": true,
    "sendDroppedEvent":    true   // covers both Not Qualified and Lost
  }
}

crmDatasetId is only needed for Meta Instant Forms. Meta keeps website events and CRM events in separate datasets, so lead stages need their own: create one in Events Manager under Connect data sources, then CRM. Leave it empty, and everything goes to the Pixel.

Worth knowing before you switch it on

  • Matching starts the day you switch it on. Older leads carry no click ID and can't be matched afterwards.
  • Meta needs a few hundred results before delivery changes. Expect three to four weeks, not three days.
  • Nothing useful reaches Meta unless your team records outcomes. If every lead stays New, Meta learns nothing.
  • Personal details are hashed with SHA-256 before sending. Meta can match them but can't read them.
  • Remove the test event code once delivery is confirmed, or real events keep landing in the test view.

Checking delivery

Copy the test event code from Events Manager into your settings, change a lead's stage, and watch the Test events tab. The event should appear within a minute or two. Instant Form events appear under the CRM dataset, not the Pixel.

Opt-outs

Every sending endpoint checks whether the contact has opted out before sending, so you stay within Meta's rules without checking yourself. A single message to an opted-out contact is refused:

// 400 Bad Request
{
  "success": false,
  "message": "Cannot send message - contact has opted out",
  "error":   "OPT_OUT_BLOCKED"
}

Errors

Errors always come back in the same shape, so your code can handle them one way:

{
  "success": false,
  "message": "What went wrong",
  "error":   "More detail (development only)"
}
CodeMeaning
200It worked
201Created
400Something in the request is wrong
401The token is missing or has expired
404That record doesn't exist
429Too many requests: wait and try again

Security

Headers

Every reply carries security headers against common attacks such as cross-site scripting and clickjacking: Content-Security-Policy, X-Content-Type-Options, X-Frame-Options: DENY and X-XSS-Protection.

Input checks

Everything sent to the API is checked and cleaned, against code injection, harmful HTML and similar attacks.

Who can call it

The API only accepts requests from the Heroshhi app. Webhook endpoints are the exception: they're open, so Meta and other services can deliver events.