Skip to main content

Application webhooks & API

Adway notifies you by webhook when something happens to an application. Each delivery is a short notification which names the application and the event. You can then read the application, and download its files, from the API.

Contents

Credentials

As part of the setup process we need to exchange credentials and URLs. These need to be communicated with your Adway contact over a trusted channel.

Supplied by you

Endpoint URL

Where we POST deliveries. Must be HTTPS on a public hostname.

Signing secret

At least 16 characters. We use it to sign every delivery so you can verify that it came from us.

Bearer token

At least 64 characters. We send it back to you as an Authorization header on every delivery.

Supplied by Adway

API access token

A signed token you present to read applications and download files.

Environment

Test https://connect-test.adway.ai/api/external-api/v2, production https://connect.adway.ai/api/external-api/v2. Tokens will differ between environments.

At least one of the secret or the token is required.

Receiving webhooks

A delivery fires when an application reaches an event that is broadcasted.

Webhook payload

The delivery tells you which application changed and what happened to it.

POST /your/endpoint  HTTP/1.1
Content-Type: application/json
Authorization: Bearer <your 64+ char token>
X-Adway-Timestamp: 1789012345678
X-Adway-Delivery: 9f2c1e7b4d8a…
X-Hub-Signature-256: sha256=4a7d9c…
{
"version": 2,
"event": "APPLICATION_QUALIFIED",
"applicationId": "6712aaaaaaaaaaaaaaaaaaaa",
"customerId": "6100aaaaaaaaaaaaaaaaaaaa"
}

Field

Meaning

version

Payload version. Currently 2.

event

Trigger event. See below.

applicationId

Affected application's ID.

Events

Event

Sent when

APPLICATION_QUALIFIED

The first time an application qualifies.

Delivery headers

Header

Sent when

Meaning

X-Adway-Timestamp

Always

Milliseconds since the Unix epoch, taken at the moment of this attempt. Part of the signed material.

X-Adway-Delivery

Always

Identifies one delivery across its retries. Retries of the same delivery repeat this value.

X-Hub-Signature-256

You gave a secret

sha256= followed by the hex HMAC. See below.

Authorization

You gave a token

Bearer plus the exact token you supplied.

Verifying a delivery

When you supply a secret, every delivery carries X-Hub-Signature-256. The signature is an HMAC-SHA256 over the timestamp and the raw body joined by a single period, hex encoded and prefixed with sha256=.

# signed material
"<X-Adway-Timestamp>" + "." + "<exact raw request body>"

# expected header value
"sha256=" + hex(hmac_sha256(secret, signed_material))

In order to verify the payload, sign the raw bytes you received. Parsing the JSON and re-serializing it will change key order or whitespace and the signature will not match.

const crypto = require("node:crypto");

function isGenuine(rawBody, headers, secret) {
const timestamp = headers["x-adway-timestamp"];
const received = headers["x-hub-signature-256"];
if (!timestamp || !received) return false;

const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");

const a = Buffer.from(received);
const b = Buffer.from(expected);

// Constant-time compare; lengths must match first.
return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Responses & retries

We expect status 200 on a successful delivery.

A failed delivery is retried a limited number of times with exponential backoff. We retry 5xx, 408, 429 and connection failures. Any other 4xx is treated as a permanent rejection and is not retried.

Idempotency

X-Adway-Delivery identifies an individual webhook event across retries/deliveries.

Application API

The API is provided to allow fetching additional data, such as the sensitive information supplied by the applicant, including the attached/generated files.

Authorization: Bearer <your Adway access token>

Get an application

GET https://connect.adway.ai/api/external-api/v2/applications/{id}

{id} is the applicationId from the delivery. The response is the application data with file metadata.

{
"id": "6712aaaaaaaaaaaaaaaaaaaa",
"customerId": "6100aaaaaaaaaaaaaaaaaaaa",
"jobPostId": "6650aaaaaaaaaaaaaaaaaaaa",
"atsJobId": "REQ-4711",
"state": "created",
"isQualified": true,
"rating": 0.82,
"score": 4,
"age": 34,
"utmSource": "linkedin",
"registrationForm": {
"fullName": "Ada Lovelace",
"email": "[email protected]",
"phone": "+46700000000",
"completedAt": "2026-09-01T08:00:00.000Z",
"upsertedToAtsAt": "2026-09-01T08:05:00.000Z"
},
"files": [
{
"id": "kK3rW1vQ0nS7bT2xY9pL",
"name": "cv.pdf",
"size": 182734,
"extension": "pdf",
"type": "cv"
},
{
"id": "aB8mN2cV5xZ1qW4eR7tY",
"name": "cover letter.docx",
"size": 20481,
"extension": "docx",
"type": "coverLetter"
},
{
"id": "pQ6yU3iO9aS2dF5gH8jK",
"name": "nursing-licence.pdf",
"size": 90112,
"extension": "pdf",
"type": "attachment"
},
{
"id": "zX4cV7bN1mQ8wE2rT5yU",
"name": "Adway Smart CV - Ada Lovelace.pdf",
"size": 241664,
"extension": "pdf",
"type": "smartCV"
}
],
"screeningQuestions": [
{
"id": "6700aaaaaaaaaaaaaaaaaaaa",
"title": "Do you hold a valid nursing licence?",
"answer": true,
"formattedAnswer": "Yes",
"upsertedToAtsAt": "2026-09-01T08:05:00.000Z"
}
],
"questions": [
{
"question": "Do you hold a valid nursing licence?",
"type": "Boolean",
"answer": true,
"source": "ScreeningQuestion"
},
{
"question": "Years of experience?",
"type": "Number",
"answer": "7",
"source": "LeadAd"
}
],
"enrichmentData": {
"cvParser": {
"name": "Ada Lovelace",
"title": "Registered Nurse",
"email": "[email protected]",
"phone": "+46700000000",
"linkedinProfile": "https://www.linkedin.com/in/ada",
"dateOfBirth": { "year": 1992, "month": 4, "day": 17 },
"location": {
"city": "Umeå",
"region": "Västerbotten",
"country": "Sweden",
"postalCode": "90325"
},
"skills": ["Triage", "Paediatrics"],
"otherQualifications": ["Driving licence B"],
"spokenLanguages": [
{ "language": "Swedish", "proficiency": "Native" }
],
"workHistory": [
{
"position": "Registered Nurse",
"company": "Norrlands universitetssjukhus",
"companyLogo": null,
"location": { "city": "Umeå", "country": "Sweden" },
"startDate": { "year": 2019, "month": 8, "day": 1 },
"endDate": null,
"responsibilities": ["Triage", "Ward rounds"]
}
],
"internships": [],
"educationHistory": [
{
"institution": "Umeå universitet",
"institutionLogoUrl": null,
"degree": "BSc Nursing",
"description": null,
"fields": ["Nursing"],
"location": { "city": "Umeå", "country": "Sweden" },
"startDate": { "year": 2015, "month": 9, "day": 1 },
"endDate": { "year": 2018, "month": 6, "day": 5 }
}
],
"references": [
{
"name": "Charles Babbage",
"position": "Ward Manager",
"company": "Norrlands universitetssjukhus",
"email": "[email protected]",
"phone": "+46700000001"
}
]
},
"linkedinProfile": {
"name": "Ada Lovelace",
"title": "Registered Nurse",
"username": "ada",
"profileUrl": "https://www.linkedin.com/in/ada",
"profileImageUrl": "https://media.example.com/ada.jpg",
"description": "Nurse with seven years in acute care.",
"location": { "city": "Umeå", "country": "Sweden" },
"skills": ["Triage"],
"spokenLanguages": [],
"workHistory": [],
"internships": []
}
}
}

This response contains sensitive personal data.

Rate limits

Responses carry the standard RateLimit-* headers.

Downloading files

The application response lists file metadata. Fetch the actual file(s) through the endpoint below:

GET https://connect.adway.ai/api/external-api/v2/applications/{id}/files/{fileId}

{fileId} is the id of an entry in the application's files array. The response is the document itself as application/octet-stream, with Content-Disposition and Content-Length set.

curl -fL \
-H "Authorization: Bearer $ADWAY_TOKEN" \
-o cv.pdf \
"https://connect.adway.ai/api/external-api/v2/applications/$ID/files/$FILE_ID"

File field

Meaning

id

File ID that you want to download.

name

Original file name, as uploaded or generated.

size

Size in bytes.

extension

pdf or docx.

type

File source. See below.

Type

Origin

What it is

cv

Candidate

The CV as uploaded.

coverLetter

Candidate

The cover letter as uploaded.

attachment

Candidate

Any further document they attached. There can be several.

smartCV

Adway

A generated, standardised CV.

plainCV

Adway

A plain-text rendering, useful for parsing.

consolidatedCV

Adway

The candidate's documents merged into one PDF.

Generated files are replaced, not versioned. When a smart, plain or consolidated CV is regenerated it gets a new id and the old one stops resolving. If a download returns 404, please fetch the application again and use the current list rather than retrying the stale ID.

Errors

Failures come back as JSON with a single error field.

Status

Means

What to do

400

The application or file ID is not a well-formed identifier.

Send the IDs exactly as they appear in the delivery and the application response.

401

Token missing, expired, revoked, or lacking the required permission.

Check the header is present and unaltered, then ask us to confirm the token's permissions.

403

The access token is not fully configured.

Misconfiguration on our side. Contact us.

404

No such application or file.

Confirm the ID is one we sent you, and that a generated CV has not since been replaced.

429

Hourly rate limit reached.

Back off and retry using the RateLimit-* headers.

502

An Adway service behind the API is unavailable.

Transient issue. Please retry with a backoff and tell us if it persists.

Going live

  1. Setup up an HTTPS endpoint that answers 2xx on properly validated deliveries.

  2. Generate a signing secret and a bearer token, at least 16 and 64 characters respectively. Send them and the URL to your Adway contact via a trusted channel.

  3. We register the webhook and issue your API access token for a test.

  4. Ask us for a test delivery and confirm that your receiver verifies the signature, rejects a tampered body, and records the applicationId as needed.

  5. Fetch that application from /v2/applications/{id}, then fetch one of its files, to prove your access token and both paths work end to end.

Regarding questions, a new secret, or a token that needs revoking: contact your Adway representative. The interactive API reference is at https://connect.adway.ai/api/external-api/v2/swagger/, and on test at https://connect-test.adway.ai/api/external-api/v2/swagger/.

Did this answer your question?