Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.firstwork.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Embed the Firstwork hiring platform inside your own application using an <iframe> and a JWT-based magic login. Candidates land directly in their application without a second sign-in, while authentication stays secure because tokens are signed on your backend with a shared secret.
If an applicant with the supplied email does not yet exist in the configured hiring flow, Firstwork automatically creates the applicant and their application using the identity claims in the JWT (email, first_name, last_name, funnel_name). If they already exist, their existing application is reused. Either way, they are logged in seamlessly inside the iframe — no separate sign-up step is required.

How it works

  • Your backend signs a short-lived JWT containing the applicant’s identity using a shared SECRET_KEY (provided by Firstwork).
  • Your frontend fetches the token from your backend and sets the iframe src to https://<company_name>.firstwork.com/magic-login/?token=<jwt>.
  • Firstwork verifies the JWT, creates or finds the applicant’s application, and logs them in inside the iframe.

Security principles

Never sign tokens in the browser. The SECRET_KEY must remain server-side. Anyone with the secret can impersonate any applicant in your hiring flow.
  • JWT authentication: JSON Web Tokens are signed with a shared secret using HS256.
  • Token generation on backend: Tokens must be generated server-side, never in the frontend.
  • Short-lived tokens: Always set an exp claim to limit exposure (e.g. 5 minutes).
  • iframe embedding: Embed Firstwork only over HTTPS using the magic login URL.

Step-by-step integration

1

Get credentials from Firstwork

Obtain your SECRET_KEY and hiring_flow_id from Firstwork. Configure the funnel in the Firstwork UI and note its funnel_name (slug).
2

Implement the backend token endpoint

Create a server-side endpoint that signs a JWT with your SECRET_KEY and returns it to the frontend. See the Node.js example below.
3

Embed the iframe in your frontend

Fetch the token from your backend and set it as the token query parameter on the magic-login URL used as the iframe src.
4

(Optional) Pass extra parameters

Append additional slug parameters (such as workplace_id) to the magic-login URL as query parameters to pre-configure the application during registration.

Code examples

const jwt = require('jsonwebtoken');
const express = require('express');
const app = express();

const SECRET_KEY = '<<provided-by-Firstwork>>';

app.get('/generate-firstwork-token', (req, res) => {
  const payload = {
    email: 'johndoe@gmail.com', // Populate dynamically
    first_name: 'John',
    last_name: 'Doe',
    hiring_flow_id: '<<provided-by-Firstwork>>',
    scope: 'LOGIN_FOR_APPLICANT',
    funnel_name: 'us-onboarding-flow',
    exp: Math.floor(Date.now() / 1000) + 5 * 60 // token valid for 5 minutes
  };

  const token = jwt.sign(payload, SECRET_KEY, { algorithm: 'HS256' });
  res.json({ token });
});

app.listen(3000, () => {
  console.log('Backend server running on port 3000');
});

JWT Payload

FieldTypeRequiredDescription
emailstringYesApplicant’s email address
first_namestringYesApplicant’s first name
last_namestringYesApplicant’s last name
hiring_flow_idstring (UUID)ConditionalHiring flow identifier provided by Firstwork. Required if funnel_name is not provided.
scopestringYesMust be LOGIN_FOR_APPLICANT
funnel_namestringConditionalFunnel slug for which the applicant will be registered. Required if hiring_flow_id is not provided.
expintegerYesExpiration as a Unix timestamp. Keep short-lived (e.g. now + 5 minutes)
JWTs must be signed with the HS256 algorithm.

Configuration

ParameterDescription
SECRET_KEYA shared secret to sign JWT tokens. Provided by Firstwork.
Firstwork URLhttps://<company_name>.firstwork.com/magic-login/

Passing extra slug parameters

To pass slug parameters for the application during registration, append them as query parameters to the iframe link:
https://<company>.firstwork.com/magic-login?token=<token>&workplace_id=<>&other_param=<>

Best practices

  1. Never expose SECRET_KEY in the frontend code.
  2. Always set a short expiration (exp) in the JWT.
  3. Only embed Firstwork domains via HTTPS.
  4. Log JWT generation events for traceability.
  5. Use HTTPS on your backend endpoint to protect token transmission.