> ## Documentation Index
> Fetch the complete documentation index at: https://developer.karmacheck.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Construct a candidate onboarding link

> How to build the candidate onboarding URL for a case so that you can display it in your own system after an order is made.

When you order a background check with the candidate-provided PII flow, KarmaCheck emails the candidate an invitation to begin onboarding. You can also build that same onboarding link yourself and display it in your own system, for example in a candidate portal or an applicant tracking screen. By the end of this guide, you'll know how to:

1. Create a case and note its ID.
2. Retrieve the invitation for the case.
3. Construct the candidate onboarding URL from the invitation token.
4. Keep the link current when an invitation is resent or about to expire.

## Before you begin

* Ensure that you have an [authentication token](/background-check-api/overview/api/authentication.md) for the KarmaCheck API.
* Order the case using the candidate-provided PII flow, where the candidate provides their own information during onboarding. See [Candidate-provided PII flow](/background-check-api/guides/candidate-provided-pii-flow.md) for the full ordering workflow. Cases that use the customer-provided PII flow don't rely on candidate onboarding.

> [!NOTE]
>
> **The link uses `invitationToken`, not `caseInvitationId`.** The Create case response returns a `caseInvitationId`, which identifies the invitation record. The onboarding URL is built from a different value, the `invitationToken`, which you retrieve in Step 2.

## Step 1: Create a case

Call [`POST /case/create`](/api-reference/cases/create-case) to order the background check. A successful response includes the IDs of the new case and its invitation:

```json theme={null}
{
  "caseId": "CASE_ID",
  "caseInvitationId": "CASE_INVITATION_ID"
}
```

Note the `caseId` value. You need it in the next step. You don't need the `caseInvitationId` to build the link.

## Step 2: Retrieve the invitation for the case

Call [`GET /invitation/case/{caseId}`](/api-reference/candidate-onboarding/get-invitation-for-case-id) to retrieve the invitation. Replace `AUTHENTICATION_TOKEN` with your token and `CASE_ID` with the `caseId` from Step 1:

```bash theme={null}
curl --request GET \
  --url https://api-stage.karmacheck.io/invitation/case/CASE_ID \
  --header 'Authorization: Bearer AUTHENTICATION_TOKEN'
```

The response includes both the ID of the invitation record and its token, along with other invitation details:

```json theme={null}
{
  "invitation": {
    "id": "d1234a8a-dd12-1e3d-98e6-5ff7eb9f7f0a",
    "invitationToken": "a1bc234-56de-7891-234a-b5c6d7c8e901",
    "expiresStamp": "2026-10-30T07:00:00.000+00:00"
  }
}
```

These are different values. The onboarding URL uses `invitation.invitationToken`, not `invitation.id`.

> [!NOTE]
>
> If no invitation exists for the case, the endpoint returns a `404` response.

## Step 3: Construct the onboarding URL

Add the `invitationToken` to the candidate onboarding URL for your environment:

| Environment | Onboarding URL | Retrieve the invitation from |
| - | - | - |
| **Staging (sandbox)** | `https://my-stage.karmacheck.com/invite/{invitationToken}` | `https://api-stage.karmacheck.io/invitation/case/{caseId}` |
| **Production** | `https://my.karmacheck.com/invite/{invitationToken}` | `https://api.karmacheck.io/invitation/case/{caseId}` |

The candidate onboarding experience uses the `my` hostname, with a suffix for the environment (`my-stage` for staging). This is a different domain from the customer-facing dashboard (`app-stage.karmacheck.com` and `app.karmacheck.com`), so make sure that you use the `my` domain when you build the link.

The following example retrieves the invitation and builds the staging URL. Encode the token so that the URL stays valid:

```javascript theme={null}
const response = await fetch(
  `https://api-stage.karmacheck.io/invitation/case/${caseId}`,
  { headers: { Authorization: `Bearer ${authenticationToken}` } }
);
const { invitation } = await response.json();

const onboardingUrl =
  `https://my-stage.karmacheck.com/invite/${encodeURIComponent(invitation.invitationToken)}`;
```

You can now display `onboardingUrl` to the candidate in your own system.

## Step 4: Keep the link current

Check `invitation.expiresStamp` before you share the link. An invitation expires 14 days after it's generated by default, and the candidate can't use the link after that.

> [!TIP]
>
> **We recommend `refreshinvite` instead of `resendinvite` to keep a link working.** [`PUT /case/id/{caseId}/action/refreshinvite`](/api-reference/candidate-onboarding/refresh-invitation-for-case) extends the expiration date of the existing invitation, so the `invitationToken` stays the same and the onboarding URL that you already built and displayed keeps working. You don't need to update anything in your system.

Use [`POST /case/id/{caseId}/action/resendinvite`](/api-reference/candidate-onboarding/resend-case-invitation) only when you need KarmaCheck to send the invitation email again. A case can have only one active invitation at a time, so resending creates a new invitation with a new ID and token.

> [!WARNING]
>
> **Fetch the invitation again after you resend an invite.** The link from the old invitation stops working when the new invitation is created. Retrieve the invitation again with `GET /invitation/case/{caseId}` and rebuild the URL from the new `invitationToken`, or your system will keep displaying a link that no longer works.

## Next steps

* Follow the [Candidate-provided PII flow](/background-check-api/guides/candidate-provided-pii-flow.md) guide to order a background check end to end.
* See [Get invitation for case ID](/api-reference/candidate-onboarding/get-invitation-for-case-id.md) for the complete invitation response.
* Review [Invitation status](/background-check-api/reference/invitation-status.md) to understand the states that an invitation can be in.
