Home AssignmentsFind freelance work InvoicingHow invoicing works PayoutsManage contractors SupportSupport and help
Country
Language
Create a free account

API/Verification

Flows

Verification (KYC / ID)

Veriff and BankID are used to verify the contractor's identity. The flow runs from an approved return URL, via one session per user, to a terminal status.

Contents

The end-to-end flow

  1. Register a return URL

    POST /verification-return-urls with the URL the user should be sent back to. The response contains requested_url and status. The approval is done manually by EasyFreelance and may take time – 201 means registered, not approved. Use GET /verification-return-urls to see the status.

  2. Start a session

    POST /users/{id}/verification/flows with provider and partner_return_url. The URL must be allowed for your partner, matched against a approved requested_url. If it is not, you get 422.

  3. Send the user to verification_url

    The response contains verification_id and verification_url. Open the URL in the end user's browser. It always points to the EasyFreelance verification page, which then forwards the user on to Veriff or BankID.

  4. The user completes and returns

    After Veriff or BankID, the user is sent back to EasyFreelance, and from there on to partner_return_url.

  5. Poll until the status is terminal

    GET /verification/status/{verificationSession} with verification_id as the ID. Poll every 2–5 seconds. Alternatively, or in addition, you can listen for employee.verified-webhook and fetch GET /users/{id} for the final result.

Providers

providerid_typeUse
verifflocalThe Veriff integration for Norwegian ID documents.
veriffinternationalThe Veriff integration that only accepts foreign documents.
bankid—BankID. id_type may be omitted, and is returned as null.
Note

id_type is required when provider is veriff. The two Veriff integrations are mutually exclusive: local does not accept foreign documents, and international does not accept Norwegian ones. Choose the right variant before you send the user on their way.

The return URL

When a session is terminal, EasyFreelance sends the user to partner_return_url with these query parameters appended. Your page must tolerate – and preferably read – them.

ParameterExample
verification_id550e8400-e29b-41d4-a716-446655440000
providerbankid or veriff
statusapproved, incomplete, error …
Do not mix these

The fields normalized_host, normalized_scheme and normalized_path_prefix in the return URL response is for display, allowlisting and uniqueness in the database. The actual matching when a flow is started is done against the stored requested_url – normalized_path_prefix is not its own “path template”.

Status values

statusTerminalMeaning
pendingNoThe session has been created, the user is not finished.
approvedYesThe provider is OK and the identity is complete.
incompleteYesThe provider is OK, but identity fields are missing.
declinedYesThe verification was rejected.
errorYesError during processing – for example a duplicate national identity number.
expiredYesThe session expired before the user finished.
cancelledYesThe user cancelled.

next_action

next_action is always set on the polling response, and tells your client what it should do next.

next_actionWhenDo this
continue_verificationpendingKeep polling.
redirect_to_partnerapprovedSend the user onward in your own flow.
retry_verificationincompleteAsk the user to restart the verification.
contact_supporterror with a duplicate national identity numberRequires manual follow-up – contact EasyFreelance.
retrydeclined and other errorsLet the user try again.
show_errorexpired, cancelledShow an error message and offer a fresh start.

id_verification_detail

The same structure is returned for GET /users/{id}, in the user list, on lookups, on polling and in the webhook. Use reason_codes for automation and partner_instructions into text you can display to the user.

reason_codeMeaning
ssn_not_providedThe provider did not return a national identity number.
ssn_duplicateThe national identity number already exists in the system. Requires manual follow-up – contact support.
birthday_not_providedThe date of birth is missing.
provider_data_incompleteThe entity is approved, but the identity data is incomplete.
veriff_missing_id_numberVeriff did not return an ID number.
veriff_missing_date_of_birthVeriff did not return a date of birth.
veriff_missing_document_countryVeriff did not return a document country.
Polling response with incomplete
{
  "verification_id": "550e8400-e29b-41d4-a716-446655440000",
  "user_id": 123,
  "provider": "bankid",
  "id_type": null,
  "status": "incomplete",
  "verified_at": "2026-07-08T12:00:00+00:00",
  "expires_at": "2026-07-08T12:30:00+00:00",
  "next_action": "retry_verification",
  "last_polled_at": "2026-07-08T12:00:05+00:00",
  "id_verification_detail": {
    "complete": false,
    "entity_status": "approved",
    "provider": "BankID",
    "missing_fields": [
      "identification"
    ],
    "reason_codes": [
      "ssn_not_provided"
    ],
    "partner_instructions": [
      {
        "code": "retry_verification",
        "message": "Identity verification partially completed. Missing national ID number."
      }
    ]
  }
}

Duplicate national identity number

If you receive status: error with ssn_duplicate, the number is already registered in the system. This cannot be resolved via the API – contact [email protected] and provide the user ID.

On GET /users/{id} the server automatically retrieves the most recent terminal ssn_duplicate-session for your partner, so that this result appears without you having to send verification_id.

Webhook

If you enable employee.verified in the API settings, we send a POST call to your callback URL when the verification is complete. That is a good alternative to frequent polling. See Webhooks.