API documentation

The Up&Up API lets you create assessments, invite candidates, read results and subscribe to events from your own tools. It is the same API our Zapier integration uses.

Authentication

Create an API key in Up&Up under Settings → API Keys. Keys start with tf_ and are shown once. Send the key as a bearer token on every request. A key belongs to one organisation and only sees that organisation's data.

curl https://upandup.work/api/zapier/auth/test \
  -H "Authorization: Bearer tf_your_key"

GET /auth/test returns your organisation's name and slug, and is the quickest way to check a key works.

Requests and errors

  • Base URL: https://upandup.work/api/zapier
  • POST bodies are JSON; GET and DELETE take query parameters.
  • Errors return a status code and { "error": "message" }. 401 means a missing or invalid key.
  • Requests are limited to 200 per minute per IP address.
  • Searches return an array; an empty array means nothing matched.

Assessments

An assessment is a test you send to candidates. It starts as a draft and must be published in Up&Up before anyone can be invited to it.

POST/actions/create-assessment

Create a draft assessment.

titlerequiredAssessment title.
descriptionShown to candidates before they start.
question_idsArray of question IDs from your question bank.
settingsObject with any of: passing_score, abandonment_hours (default 48), require_webcam, require_screen_share, require_fullscreen, track_tab_switches (default true).

Example response

{
  "test_id": "6f1a2c34-9b7d-4c21-8f10-2c9d1e77a001",
  "title": "Senior Support Agent Assessment",
  "slug": "senior-support-agent-assessment",
  "status": "draft"
}

Errors: 400 title is required

POST/actions/archive-assessment

Archive an assessment and expire its pending invitations.

test_idrequiredAssessment ID.

Example response

{
  "test_id": "6f1a2c34-9b7d-4c21-8f10-2c9d1e77a001",
  "title": "Senior Support Agent Assessment",
  "status": "archived"
}

Errors: 400 test_id is required · 400 Test is already archived · 404 Test not found

GET/searches/find-assessment

Find one assessment by title or ID.

namePart of the title. Give this or id.
idAssessment ID. Give this or name.

Example response

[{
  "id": "6f1a2c34-9b7d-4c21-8f10-2c9d1e77a001",
  "title": "Senior Support Agent Assessment",
  "slug": "senior-support-agent-assessment",
  "status": "published",
  "total_points": 40,
  "estimated_duration": 30,
  "passing_score": 70,
  "created_at": "2026-08-01T11:03:22.000Z"
}]

Errors: 400 Provide name or id

GET/searches/list-assessments

List assessments, newest first (up to 100).

statusdraft, published or archived.

Example response

[{
  "id": "6f1a2c34-9b7d-4c21-8f10-2c9d1e77a001",
  "title": "Senior Support Agent Assessment",
  "slug": "senior-support-agent-assessment",
  "status": "published",
  "total_points": 40,
  "estimated_duration": 30,
  "passing_score": 70,
  "created_at": "2026-08-01T11:03:22.000Z"
}]

Invitations and reminders

Invite a candidate to a published assessment. The candidate is created if they do not exist yet.

POST/actions/send-invite

Invite a candidate and email them their link.

test_idrequiredAssessment ID (must be published).
emailrequiredCandidate email.
namerequiredCandidate name.
expires_in_daysDays until the invitation expires.

Example response

{
  "invitation_id": "9c31b7d4-6e02-4f18-b7a5-1d84f6ce0004",
  "token": "3f9c1b7a4e8d2c60a5b1d7e9f0c2a4b6",
  "invite_url": "https://upandup.work/take/3f9c1b7a4e8d2c60a5b1d7e9f0c2a4b6"
}

Errors: 400 test_id, email, and name are required · 400 Test must be published to send invitations · 404 Test not found

POST/actions/send-reminder

Email a reminder to a candidate who has started but not finished.

test_idrequiredAssessment ID.
emailrequiredCandidate email.

Example response

{
  "success": true,
  "submission_id": "b2c6d8e0-4f31-4a90-9d12-77bb4f2a1002",
  "candidate_name": "Ada Lovelace"
}

Errors: 400 test_id and email are required · 404 Test not found · 404 Candidate not found · 404 No incomplete submission found for this candidate

Candidates

A candidate belongs to your organisation and carries one review status: pending, shortlisted or rejected.

GET/searches/find-candidate

Find a candidate by email.

emailrequiredCandidate email.

Example response

[{
  "id": "e4a91f22-1d55-4b83-a0c7-5b31c8d90003",
  "email": "ada.lovelace@example.com",
  "full_name": "Ada Lovelace",
  "phone": "+44 7700 900123",
  "review_status": "pending",
  "created_at": "2026-08-01T11:03:22.000Z"
}]

Errors: 400 email is required

GET/searches/list-candidates

List candidates, newest first (up to 100).

test_idOnly candidates invited to this assessment.
review_statuspending, shortlisted or rejected.

Example response

[{
  "id": "e4a91f22-1d55-4b83-a0c7-5b31c8d90003",
  "email": "ada.lovelace@example.com",
  "full_name": "Ada Lovelace",
  "phone": "+44 7700 900123",
  "review_status": "pending",
  "created_at": "2026-08-01T11:03:22.000Z"
}]
POST/actions/move-candidate-status

Set a candidate’s review status.

candidate_idrequiredCandidate ID.
statusrequiredpending, shortlisted or rejected.

Example response

{
  "candidate_id": "e4a91f22-1d55-4b83-a0c7-5b31c8d90003",
  "review_status": "shortlisted"
}

Errors: 400 candidate_id and status are required · 400 status must be pending, shortlisted, or rejected

Submissions and results

A submission is one candidate’s attempt at an assessment.

GET/actions/get-candidates

List submissions for an assessment with scores (up to 100).

test_idrequiredAssessment ID.
statusin_progress, completed, scored or reviewed.

Example response

[{
  "submission_id": "b2c6d8e0-4f31-4a90-9d12-77bb4f2a1002",
  "status": "completed",
  "candidate_id": "e4a91f22-1d55-4b83-a0c7-5b31c8d90003",
  "candidate_email": "ada.lovelace@example.com",
  "candidate_name": "Ada Lovelace",
  "review_status": "pending",
  "total_score": 33
}]

Errors: 400 test_id is required · 404 Test not found

GET/actions/get-results

Get the score summary for one attempt.

submission_idGive this, or test_id and email together.
test_idWith email, finds the candidate’s most recent attempt.
emailCandidate email, with test_id.

Example response

{
  "submission_id": "b2c6d8e0-4f31-4a90-9d12-77bb4f2a1002",
  "test_id": "6f1a2c34-9b7d-4c21-8f10-2c9d1e77a001",
  "test_title": "Senior Support Agent Assessment",
  "candidate_email": "ada.lovelace@example.com",
  "candidate_name": "Ada Lovelace",
  "status": "completed",
  "total_score": 33
}

Errors: 400 Provide submission_id or both test_id and email · 404 Candidate not found · 404 Submission not found

GET/actions/get-report

Get the full report for one attempt: per-question scores, proctoring summary, ID check and AI review.

submission_idrequiredSubmission ID.

Example response

{
  "submission_id": "b2c6d8e0-4f31-4a90-9d12-77bb4f2a1002",
  "test_id": "6f1a2c34-9b7d-4c21-8f10-2c9d1e77a001",
  "test_title": "Senior Support Agent Assessment",
  "candidate": { "id": "e4a91f22-1d55-4b83-a0c7-5b31c8d90003", "email": "ada.lovelace@example.com", "name": "Ada Lovelace" },
  "...": "question scores, proctoring, id_verification, ai_review"
}

Errors: 400 submission_id is required · 404 Submission not found

Webhooks

Subscribe a URL to an event and Up&Up will POST a JSON payload to it each time the event happens.

POST/hooks/subscribe

Subscribe an HTTPS URL to an event.

eventrequiredOne of the events listed below.
target_urlrequiredHTTPS URL on the public internet.

Example response

{ "id": "a7d3e1f0-2b44-4c9a-8e61-0f5d9c2b7e11" }

Errors: 400 Invalid event · 400 target_url must be an HTTPS URL · 400 target_url must not point to internal networks

DELETE/hooks/unsubscribe

Remove a subscription.

idrequiredSubscription ID, as a query parameter.

Example response

{ "success": true }

Errors: 400 Missing subscription id · 404 Subscription not found

Webhook events

assessment_createdassessment_updatedassessment_archivedassessment_expiredcandidate_invitedcandidate_startedcandidate_completedcandidate_passedcandidate_failedcandidate_abandonedcandidate_reviewedcandidate_shortlistedcandidate_rejectedcandidate_flaggedcomment_addedphone_interview_completedphone_interview_missedtranscript_readyproctoring_violation_detectedid_verification_completedid_verification_failed

Each delivery is a JSON POST like this:

{
  "id": "candidate_completed:b2c6d8e0-4f31-4a90-9d12-77bb4f2a1002:2026-08-09T09:51:07.000Z",
  "event": "candidate_completed",
  "timestamp": "2026-08-09T09:51:07.000Z",
  "submission_id": "b2c6d8e0-4f31-4a90-9d12-77bb4f2a1002",
  "test_id": "6f1a2c34-9b7d-4c21-8f10-2c9d1e77a001",
  "candidate_id": "e4a91f22-1d55-4b83-a0c7-5b31c8d90003",
  "candidate_email": "ada.lovelace@example.com",
  "candidate_name": "Ada Lovelace"
}

Questions about the API? Contact us.