Skip to main content
The sandbox is a dedicated environment for building and testing your integration. It is a fully isolated, near mirror of our production system, so you can send requests, receive responses and handle webhooks without the risk of affecting live customer data or critical production workflows. This guide covers only what is specific to the sandbox: how it differs from live, the properties, units and coverage levels pre-seeded for you, and how to trigger webhook events yourself. Everything else works the same in both environments. See Authentication, Application Lifecycle, Webhooks and Errors for how the API works, and Amending an Invite and Canceling an Application for step-by-step guides.

How the Sandbox Differs from Live

Send sandbox requests to https://api.sandbox.theguarantors.com with a sandbox API key. Live requests go to https://api.theguarantors.com, and keys only work in the environment they were issued for. See Environments. Beyond that, the sandbox differs from live in three ways:
  • Webhook events are triggered by you. Within the sandbox, we provide developers with complete control over the timing of webhook event triggers through the /v1/webhooks/trigger endpoint. This endpoint allows developers to manually and programmatically simulate the occurrence of various webhook events, thereby facilitating robust and repeatable testing of their event-handling logic. See Triggering Events in Sandbox.
  • Invite links are non-functional. Invite links returned by the sandbox POST /v1/invites endpoint will not send real emails or allow tenants to complete an application. They are intended solely for testing purposes, to allow developers to validate their integration before going live.
  • Bond documents are a sample. Bond document_link URLs returned in the sandbox always return the same sample PDF, whichever bond they belong to.

Pre-Seeded Sandbox Entities

The Sandbox environment comes preset with Properties, Units and Coverage Levels that developers can use to start testing invites and applications immediately. On the pre-seeded properties, each coverage_level resolves to the following coverage: If an invite includes a free_rent_amount or prepaid_rent_amount, its Lease Guarantee is reduced by the months of rent they cover, (free_rent_amount + prepaid_rent_amount) / monthly_rent, down to a minimum of 0. For example, a medium invite with one month of free rent gets 5 months of Lease Guarantee. These IDs can be used as inputs to the sandbox POST /v1/invites and PATCH /v1/invites/:id endpoints.

Triggering Events in Sandbox

In the sandbox environment, you have complete control over webhook event timing through the /v1/webhooks/trigger endpoint. This allows you to manually trigger webhook events for testing purposes. See Webhooks for the payloads and how they’re delivered. To trigger a webhook event in sandbox, send a POST request to:
See Trigger a sandbox webhook in the API reference for the full request and response schemas.

Request Body

The request body takes the event_type to trigger and the ID of the entity it applies to. Which ID that is depends on the event type, as listed in Available Event Types for Sandbox below. For example, application.status.started creates the application, so it takes the invite_id of the invite to convert:

Available Event Types for Sandbox

  • applicant.status.started (requires invite_recipient_id)
  • applicant.status.submitted (requires invite_recipient_id)
  • application.status.started (requires invite_id)
  • application.status.submitted (requires application_id)
  • application.status.pending (requires application_id)
  • application.status.approved (requires application_id)
  • application.status.denied (requires application_id)
  • bond.status.issued (requires application_id)
  • bond.status.canceled (requires bond_id)
For applicant events, the trigger endpoint enforces the applicant state machine (not_started → started → submitted) and cascades to the application where appropriate:
  • applicant.status.started for a recipient whose invite has no application yet creates the application and emits application.status.started in addition to applicant.status.started for that recipient. The other recipients on the invite remain not_started.
  • applicant.status.started for a recipient whose application already exists moves only that applicant to started.
  • applicant.status.submitted moves that applicant to submitted. If it is the last applicant on the application still outstanding, the application also moves to submitted and an application.status.submitted event is emitted.
  • The application-level events emit applicant events too: application.status.started (with an invite_id) emits an applicant.status.started event for every recipient on the invite, and application.status.submitted (with an application_id) emits an applicant.status.submitted event for every applicant that had not already submitted. You can use them as shortcuts instead of triggering an event for each applicant, but the two approaches can’t be mixed freely: application.status.started returns a 409 once an application exists for the invite, and application.status.submitted requires every applicant to have at least started, so it returns a 400 if any recipient is still not_started.
application.status.canceled cannot be sent through the trigger endpoint. To test it, cancel the application with POST /v1/applications/:id/cancel, which sends the webhook to your subscribed endpoint. See Canceling an Application. To cancel an issued bond, trigger bond.status.canceled through POST /v1/webhooks/trigger with the bond’s bond_id, which is returned when you trigger bond.status.issued and by GET /v1/applications/:application_id/bonds. This also cancels the bond’s application and sends application.status.canceled along with bond.status.canceled:
Invite and invite recipient events cannot be sent through the trigger endpoint either. To test them, cancel an invite with POST /v1/invites/:id/cancel or amend it with the endpoints in Amending an Invite, which send the webhooks to your subscribed endpoint.

Response

The endpoint returns the webhook payload that would be sent to subscribers:

Testing Workflow

  1. Create an invite using the POST /v1/invites endpoint
  2. Trigger application started event using the POST /v1/webhooks/trigger endpoint with the invite ID (or trigger applicant started for each invite recipient, the first one creates the application)
  3. Trigger application submitted event using the POST /v1/webhooks/trigger endpoint with the application ID (or trigger applicant submitted for each invite recipient, the last one moves the application to submitted)
  4. Trigger application approved event using the POST /v1/webhooks/trigger endpoint with the application ID
  5. Trigger bond issued event using the POST /v1/webhooks/trigger endpoint with the application ID
This allows you to simulate the complete application lifecycle and test your webhook handling. To test cancelation, create an invite and trigger application started as above, then cancel the application with POST /v1/applications/:id/cancel at any step before triggering bond issued. To test a denial, follow steps 1 through 3 above, then trigger application.status.denied with the application ID instead of application approved. A denied application can’t be issued a bond, so triggering bond issued for it returns a 400.