Getting started

Webhooks

Webhooks deliver real-time HTTP POST notifications to your endpoint when earnings call events are published — so you can react as soon as a transcript or audio file lands, instead of polling.

Availability#

Webhooks are available to ultimate_plus and enterprise_plus subscribers. On any other plan the webhook section of your account is read-only — see pricing to upgrade.

Configure an endpoint#

Add your endpoint URL on the API key page. You need an API key before a webhook can be saved. The page can also send a test delivery to your URL so you can confirm it is reachable before real events start arriving. Clearing the URL removes the webhook, and deleting your API key deletes the webhook with it.

Payload envelope#

Every webhook payload uses the same two-field envelope:

{
  "hook_type": "<event_type>",
  "hook_data": {}
}
  • hook_type — the event type identifier.
  • hook_data — the event-specific payload.

Event types#

  • EarningsCallEventsPublished — sent when one or more events have a transcript and/or audio available.

Branch on hook_type rather than assuming a single event type, so a new type added later reaches your handler as a no-op instead of an error.

{
  "hook_type": "EarningsCallEventsPublished",
  "hook_data": {
    "events": [
      {
        "company_name": "Apple Inc.",
        "symbol": "AAPL",
        "exchange": "NASDAQ",
        "year": 2023,
        "quarter": 1,
        "conference_date": "2023-02-02T17:00:00.000-05:00",
        "has_transcript": true,
        "has_audio": true
      }
    ]
  }
}

Event fields#

Each entry in hook_data.events carries:

company_namestringRequired
Company display name.
symbolstringRequired
Ticker symbol, for example AAPL.
exchangestringRequired
Exchange, for example NASDAQ or NYSE.
yearintegerRequired
Fiscal year.
quarterintegerRequired
Fiscal quarter, 14.
conference_datestringRequired
ISO 8601 datetime with timezone offset.
has_transcriptbooleanRequired
Whether the transcript is available for this call.
has_audiobooleanRequired
Whether the audio is available for this call.

Multi-event delivery#

The events array can contain more than one event in a single delivery, so always iterate it rather than reading events[0].

{
  "hook_type": "EarningsCallEventsPublished",
  "hook_data": {
    "events": [
      {
        "company_name": "Apple Inc.",
        "symbol": "AAPL",
        "exchange": "NASDAQ",
        "year": 2024,
        "quarter": 4,
        "conference_date": "2025-01-30T17:00:00.000-05:00",
        "has_transcript": true,
        "has_audio": true
      },
      {
        "company_name": "Hut 8 Corp.",
        "symbol": "HUT",
        "exchange": "NASDAQ",
        "year": 2024,
        "quarter": 4,
        "conference_date": "2025-03-03T08:30:00.000-05:00",
        "has_transcript": true,
        "has_audio": true
      }
    ]
  }
}

Receiving a webhook#

Deliveries are POST requests with Content-Type: application/json. Return a 2xx status as soon as you have accepted the payload and do any slow processing afterwards.

from flask import Flask, request

app = Flask(__name__)

@app.post("/earningscall-webhook")
def earningscall_webhook():
    payload = request.get_json()
    if payload["hook_type"] == "EarningsCallEventsPublished":
        for event in payload["hook_data"]["events"]:
            print(event["symbol"], event["year"], event["quarter"])
    # Return 2xx promptly; do the slow work afterwards.
    return "", 200
Note
Deliveries are not signed, so your endpoint cannot cryptographically verify that a request came from EarningsCall. Treat the URL itself as the secret: use HTTPS, keep the path unguessable, and validate the payload shape before acting on it.