HailMe Platform docsOpen cabinet โ†’

Send your first API notification

This example uses the isolated Render stage and FAKE delivery. It cannot prove that Twilio, FCM or APNs delivered to a real device.

1. Prepare a project

Sign in at the staging cabinet. Select your workspace, create a project and choose TEST. Open Options & channels, show SMS and save. If a sandbox route is missing, ask the operator to prepare it; no real credential is required for FAKE.

In API & SDK create a TEST service key with notifications:write, notifications:read, templates:read and usage:read. Store its value on your backend as HAILME_PLATFORM_TEST_KEY. Never print it or put it in browser/mobile code. The service key fixes the organization, project and environment; these are not caller-supplied request fields.

For priced examples, an owner must prepare test funds, activate the sample subscription and enable TEST usage billing in Billing. Set a project budget before testing limit exhaustion. Fees are samples, not an approved LIVE price.

2. Save one operation before calling

Use POST /v1/notifications with a unique Idempotency-Key of 16โ€“128 allowed characters. A UUID works. Persist the key and exact JSON body, including expiry, before the network call. After a timeout, reuse that exact pair; do not generate a new key.

{
  "channel": "SMS",
  "templateId": "sandbox.sms.v1",
  "locale": "en",
  "parameters": {"message": "Hello from my backend"},
  "recipient": {"phone": "+12025550131"},
  "clientReference": "first-test",
  "expiresAt": "<UTC instant within the next hour>"
}

The fictional number above is only for FAKE development. Replace the expiry placeholder with a future UTC ISO-8601 instant before saving operation.json.

export HAILME_PLATFORM_ORIGIN=https://platform-staging.hailme.app
# Inject HAILME_PLATFORM_TEST_KEY from backend secret storage.
# OPERATION_ID must stay unchanged for a replay of operation.json.
curl --fail-with-body "$HAILME_PLATFORM_ORIGIN/v1/notifications" \
  -H "Authorization: Bearer $HAILME_PLATFORM_TEST_KEY" \
  -H "Idempotency-Key: $OPERATION_ID" \
  -H 'Content-Type: application/json' \
  --data-binary @operation.json

Run from a trusted backend environment. Headers can be visible to local process inspection: use a secret-aware HTTP client for shared machines and production. Do not copy verbose HTTP traces into support tickets.

3. Read the result

HTTP 202 means the operation was durably admitted. Save its id. GET /v1/notifications/{notificationId} with notifications:read reports the current state. Polling is read-only. Repeating the original POST returns the admission receipt, not necessarily the newest state.

Open the same project and environment โ†’ Notification journal. Then open Usage & costs with the same date range, channel SMS and source API. Compare the settled charge, reserve and CSV. One accepted operation must not produce two charges after replay. SDK GET /v1/usage exposes counters and caps, not the owner's balance or invoice totals.

4. Handle errors deliberately

5. Verify OTP

Use independent verify:write and verify:read TEST scopes. Only test-inbox tooling should have verify:test-code:read. POST /v1/verify/verifications accepts channel SMS or EMAIL, recipient test:customer-001 and purpose signup. All mutations require a UUID Idempotency-Key and JSON, including an empty object for resend/cancel. The API reference documents checks, resend, cancel, expiry and costs. The FAKE code endpoint is never a production OTP retrieval API.

Current Verify success fee is a sample USD 0.05, reserved on create and settled once on success. Affiliated projects default to zero platform fees. Expiry, cancellation and the fifth incorrect check release the hold. Both free and priced operations obey project budgets. A successful check does not issue a customer login session.