API

API reference

7 endpoints, all GET, all read-only, all scoped to the key’s operator. Rendered from /api/v1/openapi.json, which is generated from the schemas that validate each request. Authentication and limits are on the API overview.

GET /api/v1/events

ReadIdempotentSame operation as the connector’s search_events

Search your events. The entry point for almost every workflow. Filter by part of the name, a date range or a status, and get back one row per event with its counts and gallery link. Take the id from here into the per-event tools.

Parameters

NameInTypeRequiredDescription
queryquerystring, up to 80 charactersNoPart of the event name
fromquerydate (YYYY-MM-DD)NoEarliest event date, inclusive
toquerydate (YYYY-MM-DD)NoLatest event date, inclusive
statusqueryone of "draft", "active", "archived"NoOnly events in this status.
limitqueryinteger 1 to 100default 25NoMaximum number of rows to return.

Example request

bash
curl "https://www.happyhearaudio.com/api/v1/events?query=Rivera&from=2026-11-01&to=2026-11-30&limit=10" \
  -H "Authorization: Bearer $HHA_API_KEY"

Example response

200 OK
{
  "events": [
    {
      "id": "7c1f3a2e-9b4d-4e61-8f0a-2d5c6b7e8a91",
      "event_name": "Rivera 50th Anniversary",
      "event_date": "2026-11-14",
      "status": "active",
      "unlocked": true,
      "payment_type": "per_event",
      "created_at": "2026-10-02T18:21:07.412Z",
      "updated_at": "2026-10-29T03:14:55.009Z",
      "gallery_slug": "rivera-50th-anniversary",
      "gallery_url": "https://www.happyhearaudio.com/g/rivera-50th-anniversary",
      "has_share_code": false,
      "gallery_sent": true,
      "gallery_first_opened_at": "2026-11-16T15:02:41.000Z",
      "download_enabled": true,
      "callin_enabled": true,
      "callin_start_date": "2026-11-07",
      "callin_end_date": "2026-11-21",
      "clean_level": "standard",
      "date_changes_remaining": 2,
      "messages_total": 42,
      "messages_ready": 39,
      "messages_cleaning": 2,
      "messages_waiting": 0,
      "messages_needs_attention": 1,
      "messages_hidden_by_operator": 1,
      "unique_visitors": 63,
      "total_plays": 217,
      "total_downloads": 11
    }
  ],
  "count": 1,
  "truncated": false
}

Errors

  • 400 A parameter is missing or malformed; `issues` names the field.
  • 401 No key, an unknown key, or a revoked key.
  • 403 The account is not on the Monthly plan.
  • 429 More than 60 requests in a minute for this key.
  • 503 A read on our side failed. Retry after a short wait.

Notes

  • Rows come newest event date first; events without a date sort last.
  • The name match is a case-insensitive substring. Wildcard characters in query are matched literally.
  • truncated is true when exactly limit rows came back, so there may be more: narrow the filter or raise limit (100 at most).
  • Only the signed-in operator's events are visible. Row-level security enforces this below the server, not in this code.

GET /api/v1/events/needing-attention

ReadIdempotentSame operation as the connector’s list_events_needing_attention

List events that need a look. An account-wide "is anything stuck?" check: events with a message in needs_attention, or a message still cleaning more than 30 minutes after it arrived. An empty list means nothing needs the operator.

Parameters

NameInTypeRequiredDescription
limitqueryinteger 1 to 100default 25NoMaximum number of rows to return.

Example request

bash
curl "https://www.happyhearaudio.com/api/v1/events/needing-attention?limit=25" \
  -H "Authorization: Bearer $HHA_API_KEY"

Example response

200 OK
{
  "events": [
    {
      "id": "7c1f3a2e-9b4d-4e61-8f0a-2d5c6b7e8a91",
      "event_name": "Rivera 50th Anniversary",
      "event_date": "2026-11-14",
      "messages_needing_attention": 1,
      "messages_stuck_cleaning": 0,
      "dashboard_url": "https://www.happyhearaudio.com/dashboard/events/7c1f3a2e-9b4d-4e61-8f0a-2d5c6b7e8a91"
    }
  ],
  "count": 1,
  "truncated": false
}

Errors

  • 400 A parameter is missing or malformed; `issues` names the field.
  • 401 No key, an unknown key, or a revoked key.
  • 403 The account is not on the Monthly plan.
  • 429 More than 60 requests in a minute for this key.
  • 503 A read on our side failed. Retry after a short wait.

Notes

  • Stuck is measured from the message's arrival time, so a re-clean started on an older message reads as stuck for its first 30 minutes.
  • limit bounds the candidate events checked, not the rows returned; truncated is true when the candidate list filled it.
  • When nothing is found the result carries a note field saying so, so an assistant has something to say.

GET /api/v1/events/{id}

ReadIdempotentSame operation as the connector’s get_event

Get one event. One event in full: the same row search_events returns, plus one entry per message with its number, source, state, length and whether the operator hid it. Use it when counts are not enough.

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)YesThe event id, as returned by search_events or create_event.

Example request

bash
curl "https://www.happyhearaudio.com/api/v1/events/7c1f3a2e-9b4d-4e61-8f0a-2d5c6b7e8a91" \
  -H "Authorization: Bearer $HHA_API_KEY"

Example response

200 OK
{
  "event": {
    "id": "7c1f3a2e-9b4d-4e61-8f0a-2d5c6b7e8a91",
    "event_name": "Rivera 50th Anniversary",
    "event_date": "2026-11-14",
    "status": "active",
    "unlocked": true,
    "payment_type": "per_event",
    "created_at": "2026-10-02T18:21:07.412Z",
    "updated_at": "2026-10-29T03:14:55.009Z",
    "gallery_slug": "rivera-50th-anniversary",
    "gallery_url": "https://www.happyhearaudio.com/g/rivera-50th-anniversary",
    "has_share_code": false,
    "gallery_sent": true,
    "gallery_first_opened_at": "2026-11-16T15:02:41.000Z",
    "download_enabled": true,
    "callin_enabled": true,
    "callin_start_date": "2026-11-07",
    "callin_end_date": "2026-11-21",
    "clean_level": "standard",
    "date_changes_remaining": 2,
    "messages_total": 42,
    "messages_ready": 39,
    "messages_cleaning": 2,
    "messages_waiting": 0,
    "messages_needs_attention": 1,
    "messages_hidden_by_operator": 1,
    "unique_visitors": 63,
    "total_plays": 217,
    "total_downloads": 11
  },
  "messages": [
    {
      "message_number": 1,
      "source": "callin",
      "state": "ready",
      "duration_seconds": 24,
      "hidden_from_gallery": false
    },
    {
      "message_number": 2,
      "source": "upload",
      "state": "ready",
      "duration_seconds": 41,
      "hidden_from_gallery": false
    },
    {
      "message_number": 3,
      "source": "web",
      "state": "cleaning",
      "duration_seconds": 18,
      "hidden_from_gallery": false
    },
    {
      "message_number": 4,
      "source": "callin",
      "state": "needs_attention",
      "duration_seconds": 0,
      "hidden_from_gallery": true
    }
  ],
  "dashboard_url": "https://www.happyhearaudio.com/dashboard/events/7c1f3a2e-9b4d-4e61-8f0a-2d5c6b7e8a91"
}

Errors

  • 400 A parameter is missing or malformed; `issues` names the field.
  • 401 No key, an unknown key, or a revoked key.
  • 403 The account is not on the Monthly plan.
  • 404 No event with that id in your account.
  • 429 More than 60 requests in a minute for this key.
  • 503 A read on our side failed. Retry after a short wait.

Notes

  • Message states: ready, cleaning, waiting, needs_attention, video.
  • Sources are how the message arrived: callin, sms, web or upload.
  • At most 500 messages are listed per event.
  • No audio, no transcript text, no caller details. The view the tool reads has no such columns.

GET /api/v1/events/{id}/audio-status

ReadIdempotentSame operation as the connector’s get_event_audio_status

Check audio status on an event. The cheapest way to answer "is the audio ready?" for one event: counts by state, a yes/no all_audio_ready flag and one short line per message. Smaller than get_event when you do not need durations or sources.

Parameters

NameInTypeRequiredDescription
idpathstring (uuid)YesThe event id, as returned by search_events or create_event.

Example request

bash
curl "https://www.happyhearaudio.com/api/v1/events/7c1f3a2e-9b4d-4e61-8f0a-2d5c6b7e8a91/audio-status" \
  -H "Authorization: Bearer $HHA_API_KEY"

Example response

200 OK
{
  "event_id": "7c1f3a2e-9b4d-4e61-8f0a-2d5c6b7e8a91",
  "event_name": "Rivera 50th Anniversary",
  "total": 4,
  "counts": {
    "ready": 2,
    "cleaning": 1,
    "waiting": 0,
    "needs_attention": 1,
    "video": 0
  },
  "all_audio_ready": false,
  "messages": [
    "Message 1: ready",
    "Message 2: ready",
    "Message 3: cleaning",
    "Message 4: needs attention"
  ],
  "dashboard_url": "https://www.happyhearaudio.com/dashboard/events/7c1f3a2e-9b4d-4e61-8f0a-2d5c6b7e8a91"
}

Errors

  • 400 A parameter is missing or malformed; `issues` names the field.
  • 401 No key, an unknown key, or a revoked key.
  • 403 The account is not on the Monthly plan.
  • 404 No event with that id in your account.
  • 429 More than 60 requests in a minute for this key.
  • 503 A read on our side failed. Retry after a short wait.

Notes

  • all_audio_ready is true only when there is at least one message and none is cleaning or waiting. A needs_attention message does not block it.
  • Video messages never enter the audio pipeline, so they count separately.

GET /api/v1/account/plan

ReadIdempotentSame operation as the connector’s get_plan_and_usage

Get your plan and usage. Which plan the account is on, its subscription status and paid-through date, whether the free first event is used, and how many events exist. Call it before create_event when the assistant needs to say whether the next event will need payment.

Parameters

No parameters.

Example request

bash
curl "https://www.happyhearaudio.com/api/v1/account/plan" \
  -H "Authorization: Bearer $HHA_API_KEY"

Example response

200 OK
{
  "plan": "monthly",
  "unlimited_events": true,
  "subscription_status": "active",
  "paid_through": "2026-11-23",
  "pause_ends_on": null,
  "free_event_used": true,
  "first_event_created_on": "2026-06-18",
  "events_created": 27,
  "note": "Unlimited events are included while the subscription is paid.",
  "billing_url": "https://www.happyhearaudio.com/dashboard/settings"
}

Errors

  • 401 No key, an unknown key, or a revoked key.
  • 403 The account is not on the Monthly plan.
  • 429 More than 60 requests in a minute for this key.
  • 503 A read on our side failed. Retry after a short wait.

Notes

  • plan is per_event, monthly or annual. unlimited_events is the entitlement that matters for create_event.
  • A paused subscription is paid only through paid_through; pause_ends_on says when billing resumes.
  • No card, invoice or payment detail is ever included.