API

Read opportunities, matches and agency ad counts straight from erecruit — the same data the dashboard shows, for your CRM and your own tooling.

Access

API access is part of the Agency plan. Create a key in your dashboard, then send it as a bearer token. Only a SHA-256 digest is stored, so a lost key cannot be recovered — revoke it and make another. Revoking takes effect on the next request.

curl -H "Authorization: Bearer <your-key>" \
  "https://erecruit.io/api/v1/opportunities?limit=10"

Keys have no scopes and no expiry: a key reads everything the account may read, and nothing else. A Recruiter or free account gets 402.

Endpoints

GET/api/v1/opportunitiesOpen contracts, closing soonest first. The full record, including the notice text and extracted skills.
GET/api/v1/opportunities/{externalId}One contract by its BuyICT id, such as LH-07659, open or closed.
GET/api/v1/matchesContract↔ad pairings, highest score first, with the signal breakdown behind each score.
GET/api/v1/agenciesAgencies by slug with their live and total ad counts.
GET/api/v1/contractsEvery contract with a served page — open ones plus recently closed — with the buyer and invitation label.
GET/api/v1/resumesYour own CVs: id, filename, status, size, mime and date. Never the CV text.
GET/api/v1/resumes/{id}/matchesWhat one CV was matched to, with the evidence, under the same ownership rule the dashboard applies.

Reading a response

Every list endpoint returns data and pagination. total is the size of the whole set, not of the page; nextOffset is null at the end, so a client can walk the set without guessing.

{
  "data": [],
  "pagination": {
    "limit": 50, "offset": 0, "total": 79,
    "count": 50, "hasMore": true, "nextOffset": 50
  }
}

limit is 1–200 and defaults to 50. An out-of-range value is a 400, never a silent clamp: a client that asked for 5,000 rows and quietly received 200 believes it holds the whole set.

Errors

One shape for every failure: { "error": { "code", "message" } }. The message is written to be shown to a user as-is.

401 unauthorized
No key, or a key that is not recognised. The two answer alike on purpose: telling them apart hands an attacker half the answer.
402 upgrade_required
The caller is known, but their plan does not include API access. This is the signal to offer an upgrade.
400 invalid_request
A query parameter was not usable — limit above 200, or something that is not a whole number.
404 not_found
No such record, or none this key may read. The two are deliberately indistinguishable.

OpenAPI document

The whole contract — every field, every status, every schema — is in /openapi.yaml (OpenAPI 3.1). Point a client generator or an import tool at that URL. It is written by hand rather than generated, and a test fails the build if a documented path has no route or a route is left undocumented.

What this API does not do

  • Read-only. Nothing can be created or changed, and there is no upload endpoint — CV upload stays in the dashboard, where the consent record is written.
  • No resume contents, ever. The CV text and any candidate contact details are personal data and no endpoint returns them, not even to the account that uploaded them.
  • No filtering or search yet — only limit and offset. Paging is applied to the full result set, so total is exact.
  • No rate limit on the API. The limiter the sign-in forms use is an in-process map keyed on IP, so it would neither limit across instances nor suit a CRM that shares one IP — which is why it is not applied here. Treat the API as best-effort until a per-key limit exists.
  • No webhooks. Poll the list endpoints.

Written down because a missing capability that is not stated gets assumed.

Deprecated paths

GET /api/opportunities and GET /api/matches still answer, because a key already pointed at them must keep working. They return the older body — an object keyed by resource, not the data envelope — unpaged and unsorted, with a Deprecation: true header and a Link header naming the successor. New integrations should use /api/v1/.

Get API access

API access comes with the Agency plan. Create a key and pull opportunities, matches and agency activity into your own tools.