Skip to main content
The snapshots API allows you to trigger snapshots of CRM objects for specific points in time.

Create CRM object snapshots

To create snapshots for multiple CRM objects in a single batch request, ensure your client credentials token was generated with the developer.webhooks_journal.snapshots.write scope specified, then make a POST request to /webhooks-journal/snapshots/2026-03/crm. In the request body, include the snapshotRequests property with the objects you want to snapshot. The available properties for this endpoint are listed in the table below. All fields are required.
FieldTypeDescription
snapshotRequestsArrayA list of snapshot request objects.
portalIdNumberThe ID of the HubSpot account where the object exists.
objectIdNumberThe ID of the CRM object to snapshot.
objectTypeIdStringObject type identifier (e.g., "0-1" for contacts).
propertiesArrayArray of property names to include in the snapshot.
{
  "snapshotRequests": [
    {
      "portalId": 12345,
      "objectId": 1001,
      "objectTypeId": "0-1",
      "properties": ["email", "firstname", "lastname", "phone"]
    },
    {
      "portalId": 12345,
      "objectId": 1002,
      "objectTypeId": "0-1",
      "properties": ["email", "company"]
    }
  ]
}
A successful request will return status tracking IDs for each requested snapshot:
{
  "snapshotResponses": [
    {
      "portalId": 12345,
      "objectId": 1001,
      "objectTypeId": "0-1",
      "snapshotStatusId": "550e8400-e29b-41d4-a716-446655440000"
    },
    {
      "portalId": 12345,
      "objectId": 1002,
      "objectTypeId": "0-1",
      "snapshotStatusId": "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
    }
  ]
}

You can then use the snapshotStatusId from each entry to poll for processing status detailed in the section below.

Get snapshot status

Snapshot processing is asynchronous. After creating a snapshot, use the returned snapshotStatusId from the response you received when you created the snapshot to poll for its status. Ensure your client credentials token was generated with the developer.webhooks_journal.snapshots.write scope specified, then make a GET request to /webhooks-journal/snapshots/2026-03/crm/status/{snapshotStatusId}. For example, assuming a snapshotStatusId of 550e8400-e29b-41d4-a716-446655440000, the corresponding cURL command would be:
curl -X GET \
  https://api.hubapi.com/webhooks-journal/snapshots/2026-03/crm/status/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

The response will resemble the following:
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "COMPLETED",
  "initiatedAt": 1704067200000,
  "completedAt": 1704067215000
}
Continue polling until the status in the response reaches a terminal state (i.e., COMPLETED, FAILED, or EXPIRED). The response properties are detailed in the table below:
PropertyTypeDescription
idStringThe snapshot status ID.
statusStringCurrent processing status. Possible values are:
  • PENDING: the snapshot has been accepted and is queued for processing.
  • IN_PROGRESS: the snapshot is actively being processed.
  • PROCESSING: processing finished successfully. The snapshot event is available in the journal.
  • FAILED: processing encountered an error. Check errorCode for the reason.
  • EXPIRED: the snapshot was not processed within the allowed window and has been discarded.
errorCodeStringMachine-readable failure reason. Present only when status is FAILED. Possible values are:
  • TIMEOUT: processing exceeded the allowed time limit.
  • VALIDATION_ERROR: the snapshot request contained invalid data (e.g., the object or requested properties do not exist).
  • INTERNAL_ERROR: an unexpected internal error occurred during processing.
  • PERMISSION_DENIED: the app does not have permission to access the requested object or properties.
messageStringHuman-readable detail about the status. Present on failure.
initiatedAtNumberUnix timestamp (milliseconds) when the snapshot was requested.
completedAtNumberUnix timestamp (milliseconds) when processing reached a terminal state. Absent while still pending or in progress.

Polling behavior and 404 responses

Snapshot status records are created asynchronously after the snapshot request is accepted. After creating a snapshot, there is a brief window during which polling for its status may return 404 Not Found. This is expected, since the status record is propagated across regions and will be available to retrieve after a short delay.
A 404 does not mean the snapshot itself failed. The underlying snapshot processing proceeds independently of status record creation. If a status record never appears, check your journal directly, as the snapshot may have completed successfully regardless.
The recommended polling strategy is:
  1. After creating snapshots, store each snapshotStatusId.
  2. Poll GET /webhooks-journal/snapshots/2026-03/crm/status/{snapshotStatusId} with exponential backoff (e.g., starting at 1 seconds, capped at 30 seconds).
  3. On 404, treat it as “not yet available” and retry.
  4. Stop polling when status is COMPLETED, FAILED, or EXPIRED.
  5. Enforce a maximum polling duration or attempt count (e.g., 10 minutes / 20 attempts) to avoid infinite loops.
  6. If the terminal state is never reached within that window, check your journal directly.
Last modified on April 14, 2026