Skip to main content
The Custom Links API creates the same personalized experiences available through CSV Context Pack imports. One request can accept from 1 to 500 links and returns an asynchronous job to poll.

Create a key

Create an API key in Hobbes Settings with:
  • custom_links:write to create and manage links, jobs, thumbnails, and campaigns
  • custom_links:read for read-only listing and polling
Write scope also satisfies read operations. Existing keys do not receive either scope automatically. Send one POST /api/v1/custom-links request for the entire batch. A 300-link batch is one HTTP request, but it consumes 300 creation units and, when generateThumbnails is true, up to 300 render units.
campaign can identify an existing campaign by id or create/reuse one by name. The personalization fields match the CSV import contract. externalId, displayName, and active are API-specific. prospectDomain identifies the prospect and can help logo discovery. It does not choose the published link’s delivery domain. Hobbes publishes through the organization’s active custom domain or configured Sales Agent URL. Creation returns 409 when neither is configured.
Only provide public HTTP or HTTPS image URLs. Hobbes rejects private-network targets, unsafe redirects, unsupported content types, and images larger than 10 MB.

Preserve idempotency

Creation, thumbnail regeneration, and explicit retry operations require an Idempotency-Key. Generate a stable key for one logical operation and keep it with your integration state.
  • Replaying the same key with the same request returns the original job.
  • Reusing the key with different content returns 409.
  • An idempotent replay does not consume quota again.

Poll the job

Creation returns 202 Accepted with:
  • A job summary in the response body
  • Location: /api/v1/custom-link-jobs/{job_id}
  • Retry-After: 2
Poll the Location every two seconds. After 30 seconds, back off to every five seconds. Store the response ETag and send it on the next request:
An unchanged job returns 304 Not Modified without a response body. Terminal statuses are completed, completed_with_errors, cancelled, and failed. Non-terminal statuses are queued and processing. Fetch GET /api/v1/custom-link-jobs/{job_id}/items when counters change or the job becomes terminal. Items remain in input order and independently report:
  • creationStatus for validation and link creation
  • thumbnailStatus for requested thumbnail work
  • The Custom Link id and published URL when creation succeeds
  • Structured validation, creation, or thumbnail errors when work fails
Request-level errors reject the whole request. Item-level validation errors allow otherwise valid links to proceed, so a terminal job may be completed_with_errors. Use the list and detail endpoints to filter by campaign, status, external id, email, company, date, or search text. PATCH /api/v1/custom-links/{id} updates personalization, sharing metadata, campaign membership, or active state. Thumbnail work is queued only when an affected field changes. Bulk actions can activate, deactivate, or move up to 500 links. Hard deletion is not exposed. Deactivation preserves historical attribution. Campaign endpoints create, list, rename, retrieve, and delete organizational folders. Deleting a campaign unfiles its links without deleting them.

Read engagement

Every Custom Link list and detail response includes an engagement rollup. The link-level rollup combines all activity associated with that link; it is not the journey of one person or browser. The lifecycle uses the same definitions in link and session responses: Stages only advance. Lead submission, meeting click, and meeting booking are reported as conversion flags rather than additional stages. Because they prove downstream human activity, they also advance a link or session to engaged when an earlier client event was missed. botScannedOnly identifies a server-side link resolution with no observed human open or downstream activity. Use GET /api/v1/custom-links/{id}/sessions to retrieve the sessions associated with a link. The result intentionally excludes transcripts and visitor PII. Full session detail still requires sessions:read; transcripts require the separate transcripts:read scope. loadCount counts accepted non-bot load events, while pageViewCount deduplicates those events by pageViewId. Full-screen opens are recorded independently of the real-time conversation connection. uniqueVisitorCount is the best available browser-continuity estimate. When consent and browser storage allow it, Hobbes uses a persistent anonymous browser identifier. A new browser, device, domain, private window, or cleared storage may still count separately; the identifier does not identify a person. Use visitorCountMode to interpret the total: persistentUniqueVisitorCount and ephemeralPageViewCount remain exact raw counts in either mode. When the mode is estimated, treat loadsPerUniqueVisitor as approximate because Hobbes cannot establish whether ephemeral page views came from the same returning browser. Use GET /api/v1/custom-link-campaigns/{id}/engagement for raw campaign totals. A campaign response includes generated, opened, started, engaged, lead, meeting-click, meeting-booking, bot-only, load, page-view, visitor, and session counts. It uses the same visitor certainty fields as each link. UTM attribution is session-level. Retrieve a session with GET /api/v1/sessions/{session_id} and read tracking.utmSource, tracking.utmCampaign, tracking.utmMedium, tracking.utmTerm, and tracking.utmContent. Link and campaign engagement responses do not aggregate UTM values. A generated link is not proof that an email was sent, delivered, or not bounced; join those denominators from the sending platform before calculating upper- funnel conversion rates.

Regenerate, cancel, or retry

  • POST /api/v1/custom-links/{id}/thumbnail-jobs explicitly regenerates one thumbnail.
  • POST /api/v1/custom-link-jobs/{id}/cancel requests best-effort cancellation of unfinished work.
  • POST /api/v1/custom-link-jobs/{id}/retry creates a child job for failed or selected items.
Completed work remains available after cancellation. Cancellation does not refund quota. Explicit thumbnail retries consume new render units; Hobbes’ internal retries do not.

Plan for limits

The standard per-key limit is 120 HTTP requests per minute. Additional organization-wide protections apply: Invalid items do not consume weighted quota. Hobbes validates the whole request before admission; if all otherwise valid items would exceed a quota, the request returns 429 rather than accepting an arbitrary partial batch. On 429, wait for Retry-After and inspect the remaining quota and reset headers before retrying. A 503 indicates the global queue or worker circuit breaker is unavailable; no quota is charged for rejected work.