Invitations
Create Invitation
Make a POST request to /invitations to create a new invitation. Include your API key as a Bearer token in the Authorization header.
On success, the API returns 201 Created with a complete invitation object. The most important field is assessment_url, the unique link the participant uses to start their assessments.
When the invitation is created, JOFI also generates an assessment link and sends the invitation by email and/or SMS according to the send_via_email and send_via_sms flags (unless both are false, in which case you deliver the link yourself).
Required request fields
| Field | Description |
|---|---|
first_name | Participant first name (non-empty string) |
last_name | Participant last name (non-empty string) |
email | Participant email address |
created_by_user_email | Email of the JOFI user sending the invitation. Must belong to the same account as your API key. Use the Users API route to look up valid addresses. |
These four fields are the only ones you must include in the request body. The API uses the inviter's JOFI user settings for team, assessments, email template, and notification preferences. Configure those defaults for each user in JOFI before going to production.
User defaults
When you omit the optional fields below, the API uses the inviter's JOFI user settings. Configure these defaults for each user in JOFI. That is the recommended approach. Use the API override fields only when you cannot set or change user defaults in JOFI.
| Setting | Default source | Override with (fallback only) |
|---|---|---|
| Team | Inviter's default team | team_id (use the Teams API route to list valid teams) |
| Assessments | Inviter's default assessments | assessments_to_assign (array of { "test_id": N }; use the Assessments API route for IDs) |
| Invitation email template | Inviter's default email template | email_template_id |
| Congratulations notification | Inviter's default congrats template (if configured) | Not overridable on create |
| Scheduling link | Inviter's default scheduling link (if configured) | Not overridable on create |
A request with only the four required fields will fail with 400 Bad Request unless the created_by_user_email user has a default team, default assessments, and default invitation email template configured in JOFI (the email template default is required when send_via_email is true, which is the default).
If a user is missing any of these defaults, configure them in JOFI user settings unless you have business rules that require you to pass API override fields on each request.
Optional request fields
| Field | Default | Description |
|---|---|---|
person_id | null | Recommended. Your system's identifier for this participant (any string). |
custom_id | null | Your grouping identifier (for example, a job req #). Max 50 characters. |
phone | null | Participant phone number. Required when send_via_sms is true. Normalized to E.164 format in the response. |
team_id | Inviter's default team | Fallback override. Prefer configuring the inviter's default team in JOFI. Must belong to your account. |
assessments_to_assign | Inviter's default assessments | Fallback override. Prefer configuring default assessments in JOFI. At least one assessment is required. Cannot combine Prescreen (test_id: 1) with Personality, Thinking Skills, or Career Interests (test_id: 6, 7, or 8). |
send_via_email | true | Set to false to skip sending the invitation email and deliver assessment_url yourself. |
send_via_sms | false | Set to true to also send the invitation by text message. Requires phone. |
email_template_id | Inviter's default template | Fallback override. Prefer configuring the inviter's default template in JOFI. Required when send_via_email is true unless a default template is already configured. |
ref_text | null | Reference text for some email templates. Max 60 characters. |
Example requests
{
"created_by_user_email": "jane.recruiter@jofiscore.com",
"first_name": "Linda",
"last_name": "Sample",
"email": "linda.sample@jofiscore.com",
"person_id": "1bb2141c-4100-4b21-9cd2-a998b76cf736"
}
{
"created_by_user_email": "jane.recruiter@jofiscore.com",
"first_name": "Linda",
"last_name": "Sample",
"email": "linda.sample@jofiscore.com",
"person_id": "1bb2141c-4100-4b21-9cd2-a998b76cf736",
"phone": "5551234567",
"custom_id": "ABC123",
"team_id": 100,
"assessments_to_assign": [
{ "test_id": 6 },
{ "test_id": 7 },
{ "test_id": 8 }
],
"send_via_email": true,
"send_via_sms": false,
"email_template_id": 1000,
"ref_text": "Contact Jennifer White with Questions"
}
Validation and errors
Common 400 Bad Request responses:
| Condition | Example error message |
|---|---|
| Missing or invalid participant fields | first_name: First name is required, sent_to_email: Invalid email address |
| Unknown inviter | User not found with email: jane.recruiter@jofiscore.com |
| Inviter missing a required default | User with email ... does not have a default team (also applies to does not have a default assessments to assign and missing default email template) |
Invalid team_id | team_id not found |
| Duplicate email on the same team | Team already has an invitation with email ... or Team already has a test taker with email ... |
| Duplicate email elsewhere in the account | Another team in this account already has an invitation with email ... |
| SMS without phone | Phone is required if sending via text message (SMS) |
| Invalid assessment combination | Choose either Prescreen or other assessments, but not both. |
For general HTTP status codes and authentication errors, see Errors and status codes.
With a test API key (sk_test_...), the API returns 201 Created with a fake invitation object and does not create a record. See API Keys.
Example response
Returns 201 Created.
{
"mode": "live",
"object": "invitation",
"id": 12345,
"invited_by_user": {
"id": 11111,
"first_name": "Jane",
"last_name": "Recruiter",
"email": "jane.recruiter@jofiscore.com"
},
"created_at": "2026-12-11T22:23:05.312696+00:00",
"accepted_at": null,
"first_name": "Linda",
"last_name": "Sample",
"email": "linda.sample@jofiscore.com",
"send_via_email": true,
"phone": "+15551234567",
"send_via_sms": false,
"custom_id": "ABC123",
"person_id": "1bb2141c-4100-4b21-9cd2-a998b76cf736",
"invitation_email_template": {
"id": 1000,
"display_name": "Invitation v2"
},
"ref_text": null,
"congrats_email_template": {
"id": 1001,
"display_name": "Congrats v2"
},
"send_congrats_notification": true,
"target_score_profile": null,
"invitation_assessments": [
{
"id": 6,
"display_name": "JOFI Personality Traits",
"short_name": "Personality"
},
{
"id": 8,
"display_name": "JOFI Career Interests",
"short_name": "Interests"
}
],
"assessment_url": "https://www.jofiscore.com/welcome/69608c33-1425-4123-9c49-22c5d9d7838c",
"career_navigation_url": null,
"scorecard_url": null,
"job_fit_summary_url": null,
"career_options_spotlight_url": null,
"team": {
"id": 100,
"display_name": "Recruiting"
},
"account": {
"id": 200,
"display_name": "Example Company Inc"
},
"test_taker_id": null,
"career_navigation_profile_id": null
}
List Invitations
Make a GET request to /invitations to retrieve a list of Invitations in your account. By default, results are ordered by most recently created and limited to the 50 most recent invitations.
Pass the optional custom_id or email query parameter to filter results. API callers often filter by custom_id to group candidates by job requisition number or participations by group number, for example.
GET /invitations?custom_id=ABC123
GET /invitations?email=olivia.sample@
| Query parameter | Required | Description |
|---|---|---|
custom_id | No | Filter by custom_id. Partial match, case-insensitive. Max 50 characters. |
email | No | Filter by participant email address. Partial match, case-insensitive. Max 255 characters. |
Pagination and the ability to request the next set of items is coming soon. Use has_more to determine if additional matching records exist beyond the current response. Unfiltered requests return up to 50 items; filtered requests return up to 150 items.
{
"mode": "live",
"object": "list",
"total_count": 162,
"has_more": true,
"data": [
{
"object": "invitation_list_item",
"id": 12345,
"first_name": "Liam",
"last_name": "Sample",
"email": "liam.sample@jofiscore.com",
"created_at": "2026-12-11T22:23:05.312696+00:00",
"accepted_at": "2026-12-11T22:23:27.816+00:00",
"assessment_url": "https://www.jofiscore.com/welcome/5e19b39c-053f-4b95-9e00-12c1280709cb",
"test_taker_id": 23456,
"custom_id": "ABC123",
"person_id": "1bb2141c-4100-4b21-9cd2-a998b76cf736"
},
{
"object": "invitation_list_item",
"id": 23456,
"first_name": "Olivia",
"last_name": "Sample",
"email": "olivia.sample@jofiscore.com",
"created_at": "2026-12-11T22:21:44.960799+00:00",
"accepted_at": null,
"assessment_url": "https://www.jofiscore.com/welcome/056590cb-655c-45bf-ac02-928148456445",
"test_taker_id": null,
"custom_id": "ABC456",
"person_id": "2bb2141c-4100-4b21-9cd2-a998b76cf737"
},
// truncated for brevity
{
"object": "invitation_list_item",
"id": 34567,
"first_name": "Noah",
"last_name": "Sample",
"email": "noah.sample@jofiscore.com",
"created_at": "2026-06-19T11:53:36.048918+00:00",
"accepted_at": null,
"assessment_url": "https://www.jofiscore.com/welcome/e174b92e-20aa-450e-9a8d-1f8232430ad6",
"test_taker_id": null,
"custom_id": "ABC456",
"person_id": "3bb2141c-4100-4b21-9cd2-a998b76cf738"
},
{
"object": "invitation_list_item",
"id": 45678,
"first_name": "Emma",
"last_name": "Sample",
"email": "emma.sample@jofiscore.com",
"created_at": "2026-06-19T11:51:01.87555+00:00",
"accepted_at": null,
"assessment_url": "https://www.jofiscore.com/welcome/674cf088-bbca-46e5-a1c4-48ada07c19e5",
"test_taker_id": null,
"custom_id": "ABC789",
"person_id": "4bb2141c-4100-4b21-9cd2-a998b76cf739"
}
]
}
{
"mode": "live",
"object": "list",
"total_count": 2,
"has_more": false,
"data": [
{
"object": "invitation_list_item",
"id": 23456,
"first_name": "Olivia",
"last_name": "Sample",
"email": "olivia.sample@jofiscore.com",
"created_at": "2026-12-11T22:21:44.960799+00:00",
"accepted_at": null,
"assessment_url": "https://www.jofiscore.com/welcome/056590cb-655c-45bf-ac02-928148456445",
"test_taker_id": null,
"custom_id": "ABC456",
"person_id": "2bb2141c-4100-4b21-9cd2-a998b76cf737"
},
{
"object": "invitation_list_item",
"id": 34567,
"first_name": "Noah",
"last_name": "Sample",
"email": "noah.sample@jofiscore.com",
"created_at": "2026-06-19T11:53:36.048918+00:00",
"accepted_at": null,
"assessment_url": "https://www.jofiscore.com/welcome/e174b92e-20aa-450e-9a8d-1f8232430ad6",
"test_taker_id": null,
"custom_id": "ABC456",
"person_id": "3bb2141c-4100-4b21-9cd2-a998b76cf738"
}
]
}
Get Invitation by ID
Make a GET request to /invitations/:invitationId to retrieve a complete invitation object for one participant. Returns 400 Bad Request if the invitation does not exist or does not belong to your account. With a test API key, returns a fake invitation object regardless of the ID.
{
"mode": "live",
"object": "invitation",
"id": 12345,
"invited_by_user": {
"id": 11111,
"first_name": "Jane",
"last_name": "Recruiter",
"email": "jane.recruiter@jofiscore.com"
},
"created_at": "2026-12-11T22:23:05.312696+00:00",
"accepted_at": "2026-12-11T22:23:27.816+00:00",
"first_name": "Linda",
"last_name": "Sample",
"email": "linda.sample@jofiscore.com",
"send_via_email": true,
"phone": "+15551234567",
"send_via_sms": false,
"custom_id": "ABC123",
"person_id": "1bb2141c-4100-4b21-9cd2-a998b76cf736",
"invitation_email_template": {
"id": 1000,
"display_name": "Invitation v2"
},
"ref_text": null,
"congrats_email_template": {
"id": 1001,
"display_name": "Congrats v2"
},
"send_congrats_notification": true,
"target_score_profile": null,
"invitation_assessments": [
{
"id": 6,
"display_name": "JOFI Personality Traits",
"short_name": "Personality"
},
{
"id": 8,
"display_name": "JOFI Career Interests",
"short_name": "Interests"
}
],
"assessment_url": "https://www.jofiscore.com/welcome/69608c33-1425-4123-9c49-22c5d9d7838c",
"career_navigation_url": "https://www.careernavigation.org?c=CNP1234567890",
"scorecard_url": "https://www.jofiscore.com/team/100/test-takers/12345/scorecard",
"job_fit_summary_url": "https://www.jofiscore.com/test-takers/CNP1234567890/job-fit?r=jfs&zones=1_5",
"career_options_spotlight_url": "https://www.jofiscore.com/test-takers/CNP1234567890/job-fit?r=cor&zones=1_5",
"team": {
"id": 100,
"display_name": "Recruiting"
},
"account": {
"id": 200,
"display_name": "Example Company Inc"
},
"test_taker_id": 12345,
"career_navigation_profile_id": "CNP1234567890"
}
Update Invitation by ID
Make a PUT request to /invitations/:invitationId with the fields to update in the request body. Returns 200 OK with the updated invitation object.
Updatable fields
All fields are optional in the request body. Include only the fields you want to change.
| Field | Description |
|---|---|
first_name | Participant first name |
last_name | Participant last name |
email | Participant email |
phone | Participant phone (E.164 format in responses) |
custom_id | Grouping identifier (max 50 characters) |
person_id | Your system's participant identifier |
ref_text | Reference text for some email templates (max 60 characters) |
send_via_email | Whether JOFI sends the invitation by email |
send_via_sms | Whether JOFI sends the invitation by SMS (requires phone) |
email_template_id | Invitation email template ID |
send_congrats_notification | Whether to send a congratulations notification after completion |
congrats_email_template_id | Congrats email template ID |
assessments_to_assign | Array of { "test_id": N } |
You cannot update assessments_to_assign after the invitation has been accepted (accepted_at is set).
For resource-not-found and validation errors, see Errors and status codes.
// body
{
"first_name": "Lindsay",
"email": "lindsay.sample@jofiscore.com"
}
// response
{
"mode": "live",
"object": "invitation",
"id": 12345,
"invited_by_user": {
"id": 11111,
"first_name": "Jane",
"last_name": "Recruiter",
"email": "jane.recruiter@jofiscore.com"
},
"created_at": "2026-12-11T22:23:05.312696+00:00",
"accepted_at": null,
"first_name": "Lindsay",
"last_name": "Sample",
"email": "lindsay.sample@jofiscore.com",
"send_via_email": true,
"phone": "+15551234567",
"send_via_sms": false,
"custom_id": "ABC123",
"person_id": "1bb2141c-4100-4b21-9cd2-a998b76cf736",
"invitation_email_template": {
"id": 1000,
"display_name": "Invitation v2"
},
"ref_text": null,
"congrats_email_template": {
"id": 1001,
"display_name": "Congrats v2"
},
"send_congrats_notification": true,
"target_score_profile": null,
"invitation_assessments": [
{
"id": 6,
"display_name": "JOFI Personality Traits",
"short_name": "Personality"
},
{
"id": 8,
"display_name": "JOFI Career Interests",
"short_name": "Interests"
}
],
"assessment_url": "https://www.jofiscore.com/welcome/69608c33-1425-4123-9c49-22c5d9d7838c",
"career_navigation_url": null,
"scorecard_url": null,
"job_fit_summary_url": null,
"career_options_spotlight_url": null,
"team": {
"id": 100,
"display_name": "Recruiting"
},
"account": {
"id": 200,
"display_name": "Example Company Inc"
},
"test_taker_id": null,
"career_navigation_profile_id": null
}
Response fields
invitation object
Returned by POST /invitations, GET /invitations/:invitationId, and PUT /invitations/:invitationId.
| Field | Description |
|---|---|
mode | "live" or "test" depending on your API key |
object | Always "invitation" |
id | Invitation ID |
invited_by_user | JOFI user who sent the invitation ({ id, first_name, last_name, email }), or null |
created_at | ISO 8601 timestamp when the invitation was created |
accepted_at | ISO 8601 timestamp when the participant accepted the invitation, or null |
first_name | Participant first name |
last_name | Participant last name |
email | Participant email address |
send_via_email | Whether JOFI sends the invitation by email |
phone | Participant phone in E.164 format, or null |
send_via_sms | Whether JOFI sends the invitation by SMS |
custom_id | Your grouping identifier, or null |
person_id | Your system's participant identifier, or null |
invitation_email_template | Assigned invitation email template ({ id, display_name }), or null |
ref_text | Reference text for some email templates, or null |
congrats_email_template | Assigned congrats email template ({ id, display_name }), or null |
send_congrats_notification | Whether JOFI sends a congratulations notification after completion |
target_score_profile | Target score profile ({ id, display_name, short_name }), or null |
invitation_assessments | Assessments assigned to this invitation (array of { id, display_name, short_name }) |
assessment_url | Unique link for the participant to start assessments, or null |
career_navigation_url | Career Navigation URL, or null |
scorecard_url | JOFI scorecard URL, or null |
job_fit_summary_url | Job Fit Summary report URL, or null |
career_options_spotlight_url | Career Options Spotlight report URL, or null |
team | Team the invitation belongs to ({ id, display_name }) |
account | Account the invitation belongs to ({ id, display_name }) |
test_taker_id | Test taker ID after acceptance, or null |
career_navigation_profile_id | Career Navigation profile ID, or null |
List envelope (GET /invitations)
| Field | Description |
|---|---|
mode | "live" or "test" depending on your API key |
object | Always "list" |
total_count | Total number of invitations matching the request (all in your account, or all matching the provided filters) |
has_more | true if more matching items exist beyond the current response. Unfiltered requests return up to 50 items; filtered requests return up to 150 items. |
data | Array of invitation_list_item objects |
invitation_list_item fields
| Field | Description |
|---|---|
object | Always "invitation_list_item" |
id | Invitation ID |
first_name | Participant first name |
last_name | Participant last name |
email | Participant email address |
created_at | ISO 8601 timestamp when the invitation was created |
accepted_at | ISO 8601 timestamp when the participant accepted the invitation, or null |
assessment_url | Unique link for the participant to start assessments, or null |
test_taker_id | Test taker ID after acceptance, or null |
custom_id | Your grouping identifier, or null |
person_id | Your system's participant identifier, or null |