Skip to main content
The journal API endpoints provide access to historical event data stored in chronological order, allowing you to query for changes that occurred for your subscriptions over the past 3 days. These endpoints are optimized for performant access to object and property change data, especially compared to alternatives like the CRM search API.

Before you get started

You’ll need to generate a client credentials token to use the webhook journals API. More information on how to generate this token is available in the authentication section of overview article.

Retrieve journal data

The journal API has two variants:
  • Global journal (/webhooks-journal/journal/2026-03/...): returns events across all accounts where the app is installed.
  • Local journal (/webhooks-journal/journal-local/2026-03/...): returns events scoped to a specific account where the app is installed, identified by the optional installPortalId query parameter.
The sections below outline out how to retrieve the earliest, latest, or next entry in the journal.
  • When using each of these endpoints, you’ll need to ensure your client credentials token was generated with the developer.webhooks_journal.read scope specified.
  • A successful response will include a url property, which you can then use to retrieve the file for the associated journal data.

Get earliest journal entry

To retrieve the earliest available journal entry for your app, make a GET request to /webhooks-journal/journal/2026-03/earliest. The response will resemble the following:
{
  "url": "https://s3.amazonaws.com/bucket/path/to/journal/file.json",
  "expiresAt": "2024-01-01T12:00:00Z",
  "currentOffset": "550e8400-e29b-41d4-a716-446655440000"
}

Get latest journal entry

To retrieve the latest available journal entry for your app, make a GET request to /webhooks-journal/journal/2026-03/latest. The response will resemble the following:
{
  "url": "https://s3.amazonaws.com/bucket/path/to/journal/file.json",
  "expiresAt": "2024-01-01T12:00:00Z",
  "currentOffset": "550e8400-e29b-41d4-a716-446655440000"
}

Get next journal entry

To retrieve the next journal entry after a specific offset, make a GET request to /webhooks-journal/journal/2026-03/offset/{offset}/next. The offset path parameter is the UUID offset from the previous journal entry. For example, using the response from the previous sections, you’d make a GET request to /webhooks-journal/journal/2026-03/offset/550e8400-e29b-41d4-a716-446655440000/next.
{
  "url": "https://s3.amazonaws.com/bucket/path/to/journal/file.json",
  "expiresAt": "2024-01-01T12:00:00Z",
  "currentOffset": "550e8400-e29b-41d4-a716-446655440000"
}

Batch journal operations

Use batch operations for efficient retrieval of multiple journal entries in a single request, which improves throughput for high-volume data processing. All batch endpoints are exempt from the standard daily and per-second API rate limits, but are still subject to the journal-specific rate limits detailed at the bottom of this article. When using each of the batch endpoints, you’ll need to ensure your client credentials token was generated with the developer.webhooks_journal.read scope specified.

Batch retrieve by offset

To retrieve multiple journal entries by offset UUID, make a POST request to /webhooks/2026-03/journal/batch/read. In the request body, provide the list of offset UUIDs within the inputs array. The code block below provides an example JSON payload to include in your request body, along with an example cURL request to retrieve journal entries using three offset UUIDs:
  {
    "inputs": [
      "550e8400-e29b-41d4-a716-446655440000",
      "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "a3bb189e-8bf9-3888-9912-ace4e6543002"
    ]
  }

Batch retrieve range of entries from an offset

To retrieve a set number of journal entries that follow a given offset, make a GET request to /webhooks/2026-03/journal/batch/{offset}/next/{count}. Entries after the specified offset are returned in order, so the latest entry can be used as the offset for the next batch. You can also provide an optional installPortalId query parameter to filter results to a specific HubSpot account. For example, to retrieve 10 entries after offset 550e8400-e29b-41d4-a716-446655440000, you could make the following cURL request:
curl -X GET \
  "https://api.hubapi.com/webhooks-journal/journal/2026-03/batch/550e8400-e29b-41d4-a716-446655440000/next/10" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Batch retrieve earliest entries

To retrieve the earliest entries in the journal for your app, make a GET request to /webhooks-journal/journal/2026-03/batch/earliest/{count}. This is useful for an initial backfill or replaying from the beginning of the journal. You can also provide an optional installPortalId query parameter to filter results to a specific HubSpot account. For example, to retrieve the five earliest entries in the journal, you could make the following cURL request:
curl -X GET \
  "https://api.hubapi.com/webhooks-journal/journal/2026-03/batch/earliest/5" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Batch retrieve latest entries

To retrieve the latest entries in the journal, make a GET request to /webhooks-journal/journal/2026-03/batch/latest/{count}. This can be useful for catching up after a gap in your data, or checking the most recent activity for your subscriptions. You can also provide an optional installPortalId query parameter to filter results to a specific HubSpot account. For example, to retrieve the five most recent entries in the journal, you could make the following cURL request:
curl -X GET \
  "https://api.hubapi.com/webhooks-journal/journal/2026-03/batch/latest/5" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Batch endpoint response format

All batch endpoints return the same response format that includes the following properties:
PropertyTypeDescription
statusStringThe state of the request.
startedAtStringAn ISO 8601 formatted timestamp denoting the time the request was initiated.
completedAtStringAn ISO 8601 formatted timestamp denoting the time the request was completed.
resultsArrayA list of journal entries that match the parameters provided in the request.
numErrorsNumberThe number of errors that occurred while processing the request.
errorsArrayA list of the detailed errors that occurred while processing the request.
The code block below provides an example successful response with a single journal entry returned:
{
  "status": "COMPLETE",
  "startedAt": "2024-01-01T12:00:00.000Z",
  "completedAt": "2024-01-01T12:00:00.123Z",
  "results": [
    {
      "url": "https://s3.amazonaws.com/bucket/path/to/journal.json",
      "expiresAt": "2024-01-01T13:00:00.000Z",
      "currentOffset": "550e8400-e29b-41d4-a716-446655440000"
    }
  ],
  "numErrors": 0,
  "errors": []
}
If one or more entries failed to be returned, they’ll appear in the errors array. The failed offset UUID is located within context.offset[0] of each error element. An example internal error is shown below:
{
  "status": "error",
  "category": "INTERNAL_SERVER_ERROR",
  "message": "An internal error occurred while processing this journal entry. Please try again later.",
  "context": {
    "offset": ["a3bb189e-8bf9-3888-9912-ace4e6543002"]
  },
  "errors": [],
  "links": {}
}
Common error statuses you might encounter are detailed in the table below:
StatusDescription
NOT_FOUNDNo journal entry exists for the given offset.
PRESIGNING_ERRORThe entry exists but a signed URL could not be generated. Retrying the offset may succeed.
VALIDATION_ERRORBatch size exceeds the maximum allowed limit of 100 entries.

Get journal status

To retrieve the status of a journal snapshot operation, make a GET request to /webhooks-journal/journal/2026-03/status/{statusId}, where statusId is the UUID returned when a snapshot was requested.

Local journal

The local journal endpoints follow the same pattern as the global journal, but are scoped to a specific account. Use the installPortalId query parameter to specify the account.
  • GET /webhooks-journal/journal-local/2026-03/earliest
  • GET /webhooks-journal/journal-local/2026-03/latest
  • GET /webhooks-journal/journal-local/2026-03/offset/{offset}/next
  • GET /webhooks-journal/journal-local/2026-03/status/{statusId}

Rate limits

The journal API endpoints are subject to a limit of 100 requests per second per app. Learn more about the related rate limits for the management APIs here.
Last modified on April 14, 2026