---
name: lever-oauth-app
description: Establishes which Lever credential a connector actually needs and obtains it — partner-gated OAuth2 (client ID and secret issued by hand by the Lever integrations team, only after the partner program and a sandbox account), customer-created Data API keys, and the public unauthenticated Postings API — with the mandatory `audience` parameter, the `<resource>:<action>:admin` scope grammar, the Super Admin rule, sandbox-vs-production hosts that are not interchangeable, refresh-token lifetimes and a safe credential handoff. Use when asked to get Lever OAuth credentials, register a Lever app, become a Lever integration partner, obtain a Lever API key or sandbox account, or fix a Lever auth error like a consent screen showing only `offline_access`, `ClientID not found`, `Unable to find a signing key that matches`, or a connection that dies after a quiet quarter. For any other vendor's developer portal, use that vendor's skill instead.
---

# Lever API Credentials

**Read this first: there is no Lever developer portal where you register an app and walk away with a client ID and
secret.** Lever's own OAuth page says it plainly — "OAuth is part of our partner integration program, and apps must be
registered" — and registration means a form you submit to Lever, after which, in Lever's words, "someone on the Lever
team will create your OAuth app and send over your ClientID and Secret." Humans issue the credentials, by hand, and
only to approved partners. Worse for anyone hoping to shortcut it: Lever states that it does **not** hand out API keys
for partner development either ("OAuth is a requirement of the integrations program, and for that reason we do not
provide API Keys for development"). If the user's goal is "get Lever OAuth credentials this afternoon," the honest
answer is that it is not available at any price without the partner program, and the run should stop at §3.

What *is* self-serve is different, and it is what most people actually have: **a Lever customer can create their own
Data API key** inside their own account, in Settings, in about a minute. That key is HTTP Basic (key as username,
empty password), scoped to endpoints the Super Admin ticks at creation time, and valid only for that one Lever account
and that one environment. A platform can run on this — you ask each customer to generate a key and paste it in — and
it is the only path open to a non-partner. Decide which of the two models you are building against before doing
anything else (§1).

Three more things cost real time here: the **`audience` parameter** that is not optional and whose absence produces a
consent screen listing nothing but `offline_access` (§5), the **sandbox and production hosts that share no
credentials and not even the same auth server** (§4), and the **Super Admin rule** — only a Super Admin can authorize
your app or mint a key at all (§6).

## Inputs to collect before you start

Ask in one batch. Never invent.

| Input | Notes |
| --- | --- |
| **Which credential model** | Partner OAuth, or per-customer Data API keys? (§1) |
| **Partner status** | Has the partnership interest form been submitted / approved? Is there a sandbox account? (§3) |
| **Integration name** | Company or product name customers will recognize; goes on the consent screen (§4) |
| **Description**, 20–140 characters | Lever enforces both bounds; shown in the Lever ecosystem (§4) |
| **Square logo URL** | A direct image link, ~150×150, **not** a Google Drive or download link (§4) |
| **Callback URI(s)** | Every one, up front; separate apps per environment (§4, §5) |
| **Scope set** | Exact `<resource>:<action>:admin` strings, plus `offline_access` (§6) |
| **Environment** | Sandbox and production are two apps with two credential pairs (§4) |
| **Data centre** | US or EU customers — the API host differs (§5) |

## Quick Start

1. Establish which **credential model** this needs — partner OAuth or per-customer API keys (§1). Most wrong turns start here.
2. Confirm whether credentials already exist worth reusing — re-issuing orphans every existing authorization (§2).
3. If partner OAuth: submit the partnership interest form, get approved, get a sandbox account (§3).
4. Submit the OAuth registration form with name, description, callbacks, logo and scopes; Lever emails back the pair (§4).
5. Build against **sandbox** hosts, including the sandbox auth server — it is a different domain entirely (§5).
6. Pin down scopes *and* that the authorizing user is a **Super Admin** — neither substitutes for the other (§6).
7. Check rate limits, confidential-data access and plan-gated endpoints before promising a launch date (§7).
8. Verify with a real authorize → callback → refresh → refresh-again round trip, against a second account (§8).
9. Hand the secret to a human, never to source control (§9).

## Platform state (verified 2026-09-20 — re-verify before trusting)

- **OAuth credentials are issued by Lever staff, not by a portal.** Both the OAuth page and the Partner page say so.
  There is no console where a developer creates an app.
- **The "register" button on Lever's own OAuth and Partner pages is misdirected.** As of this verification it links to
  `https://hire.lever.co/settings/integrations` — a *customer's* own Lever settings page, which just bounces an
  anonymous visitor to a login screen. It is not a registration form. Do not send a user to click it and expect a
  form; ask the Lever integrations team (`integration-support@lever.co`) for the current registration form link, or
  start from the partnership interest form (§3). Re-check whether this has been fixed before writing it off.
- **Since 2020, all Lever *integrations* are OAuth.** API keys remain, explicitly, for customers building their own
  internal workflows.
- **Sandbox runs on a different identity provider.** Production authorizes at `https://auth.lever.co`; sandbox
  authorizes at `https://sandbox-lever.auth0.com`. Both are Auth0 underneath (a bare production authorize request
  returns an Auth0-styled error page), which explains the `audience` parameter and the scope grammar.
- **The EU data centre is documented inconsistently.** The US OAuth page says EU is handled for you — "Any integration
  authorization or action will be re-directed automatically to the appropriate data center." But Lever's EU copy of
  the API docs (`https://hire.eu.lever.co/developer/documentation`) documents EU-specific hosts:
  `https://auth.eu.lever.co/authorize`, `https://auth.eu.lever.co/oauth/token` and audience
  `https://api.eu.lever.co/v1/`. On 2026-09-20, `https://api.eu.lever.co` answered (401, as an authenticated host
  should) but every path probed on `auth.eu.lever.co` returned 404. **Do not pick one and build on it.** Ask Lever
  which auth host EU customers must use, and test it before you promise EU support.
- **Lever is an Employ Inc. product** (alongside JazzHR and Jobvite). Partner and marketing pages sit on
  `lever.co`; the partner ecosystem now lives at `marketplace.lever.co` (`leverpartner.com` redirects there).
- **The partner help centre is behind a login.** `partnerexperience.lever.co` returned 401 unauthenticated, so any
  step documented only there cannot be read from outside — a reason to ask the partner contact rather than guess.
- **The API is still v1 and actively maintained** — the changelog shows new endpoints in April 2026 (deleted
  applications, deleted postings, opportunity file actions, application HTTP metadata fields).

If the developer pages do not look like this, stop and report what you actually see.

## 1. Which credential, and who can get it

| Surface | Credential | Hosts | Who gets it |
| --- | --- | --- | --- |
| **Data API** (core ATS read/write) via **OAuth 2.0** | Client ID + secret, authorization code grant | authorize/token on `auth.lever.co`; API `api.lever.co/v1/` | **Approved partners only**, issued by Lever staff (§3, §4) |
| **Data API** via **API key** | Single key, HTTP Basic — key as username, **empty password** | `api.lever.co/v1/` | Any customer Super Admin, self-serve, for their own account (§4 Path B) |
| **Postings API** | **None — public and unauthenticated** | `api.lever.co/v0/postings/<site>` | Anyone. A live probe on 2026-09-20 returned HTTP 200 with no credentials at all |

Consequences worth stating out loud before anyone starts work:

- **The Postings API is not a cheaper Data API.** It returns only *published* job postings for a company's job site —
  Lever's own FAQ says internal, closed and draft postings are visible solely through the authenticated Data API. It
  is the right tool for a careers page or a job-board feed (`?mode=xml`), and useless for anything candidate-shaped.
- **An API key is per-account and per-environment.** A key minted in a sandbox tells you nothing about production, and
  a key from customer A cannot read customer B. There is no multi-tenant API key.
- **The two models differ in who your customers can be.** Lever's partner FAQ states that integrations using OAuth and
  programmatic webhooks are available to **all** customers, whereas older API-key integrations and manually configured
  webhooks require the customer to have the **Data API** and **Webhook** features in their plan. Choosing the API-key
  path therefore narrows your addressable customers, quietly, by plan tier.

> **Product fact — dated.** As of **2026-09-20**, Unified.to's Lever connector supports **both** models: OAuth 2.0 and
> an API-key mode that uses the documented Basic scheme with the key as username and an empty password. It records
> **two** environments and no others — **Production** (API `https://api.lever.co/v1/`, authorize
> `https://auth.lever.co/authorize`, token `https://auth.lever.co/oauth/token`, audience `https://api.lever.co/v1/`)
> and **Sandbox** (API `https://api.sandbox.lever.co/v1/`, authorize and token on `https://sandbox-lever.auth0.com`,
> audience `https://api.sandbox.lever.co/v1/`) — so there is **no EU-specific entry**, which matters given the EU host
> discrepancy above. It sends `audience` as an authorize-time parameter, and sends client ID and secret in the token
> request **body** rather than as HTTP Basic. It ships **no shared Unified.to OAuth credentials for Lever**: every
> workspace must supply its own client ID and secret, which in practice means its own Lever partnership. Its scope
> sets are the granular `<resource>:<action>:admin` strings chosen per unified object — `offline_access` on every set,
> plus `opportunities`, `contact`, `resumes`, `postings`, `users`, `interviews`, `stages`, `files`, `notes` and
> `webhooks` at `:read:admin` or `:write:admin` — with a login/authorize set of `offline_access` plus opportunities
> read and write. It collapses a read scope into the matching write scope when both would be requested, which mirrors
> Lever's documented de-duplication behaviour (§6). It does **not** request `confidential:access:admin`, requisition,
> offer, EEO or form scopes, and interview *write* is not currently enabled. Its sandbox is recorded as not
> self-serve, gated on partner approval, with a named Lever partner contact. **Confirm all of this with the
> connector's owner before acting on it** — connector configuration changes independently of this skill.

## 2. Reuse the existing credentials, or request new ones

New partner credentials mean a **new client ID, and every existing customer authorization is bound to the old one** —
every customer re-authorizes. Reuse what exists for: adding a callback URL, adding a scope, rotating a compromised
secret, or diagnosing a failure. Lever handles all four on the existing app, by request (§4).

Request a **new** app only when the user explicitly wants one: a separate product, a replacement for a compromised
client, or the deliberate sandbox → production promotion, which *is* a second app by design (§4). Say which path you
are taking before you start.

For **per-customer API keys** the calculus is gentler: each key is independent, so rotating one affects exactly one
tenant — but note that a regenerated key is a hard cutover, with no grace window documented.

## 3. Accounts: the partner program, and a sandbox to build in

**The partner program is the gate.** Start at the partnership interest form
(`https://www.lever.co/partnershipinterest`) — Lever's stated sequence is: submit the form → internal review by the
partnerships team → sandbox access → go live in the marketplace. What the run needs to know:

- **Approval comes before anything technical.** Lever provides the sandbox account only once you are approved; the
  sandbox is not available to someone evaluating whether to build.
- **Completing and releasing an integration is a requirement of partnership**, per Lever's partner FAQ. Partnership is
  not a credential you collect and sit on.
- **Lever will not give you a customer list.** Their FAQ says so explicitly, so do not plan an outreach step around it.
- **Production credentials are the *last* step, not the first.** Lever's four-step process is: register for sandbox
  OAuth → build → submit to move to production → finalize. Moving to production requires a help-centre article you
  write, **two sandbox logins created for `sadmin@levertest.com` and `integration-support@lever.co`**, ecosystem
  listing copy, technical support contact details, and a live **QA run-through call** where you screen-share the whole
  customer journey. Only after that does Lever issue production OAuth credentials. Plan in weeks, not days.
- The agreement, co-marketing and listing terms are **business decisions**. Do not fill in revenue, security or
  compliance claims on the user's behalf — collect the questions and hand them back.

**The sandbox has one behaviour that wastes an afternoon if you do not know it: email is turned off.** Invited users
receive no invitation email and must sign in through the login link directly. A warning about this appears in the
sandbox UI and is expected.

Anything requiring a human — submitting the interest form, email verification, scheduling the QA call, accepting terms
— hand back rather than looping.

**If this session has no browser automation** (the usual case for a CLI or cloud run), do not pretend to click. Give
the user an exact, ordered click path with the literal values to paste — the callback URLs from §5 and the scope
strings from §6 — or a ready-to-send message to `integration-support@lever.co`, then continue once they report back
with the client ID.

## 4. Obtaining the credentials

### Path A — Partner OAuth, for a multi-tenant connector

Registration is a **form you submit and a human fulfils**. Lever's OAuth page lists exactly five things it asks for:

1. **Integration name** — your company name, or the product being connected.
2. **Description** — **between 20 and 140 characters**, enforced. It is displayed in the Lever integration ecosystem.
3. **Callback URI(s)** — see §5. On sandbox these may be `http`; in production they may not.
4. **Square logo URI** — a real image link. Lever explicitly rejects a Google Drive link or a link to a download.
   Square, recommended 150×150, rendered on a white background in both the product and the authorization module.
5. **Required scopes** — the exact strings (§6). Lever says most use cases need **5 to 8**, with an **absolute
   maximum of 20**.

Lever's guidance worth heeding: **save a copy of your submission.** You will want it when debugging, because nothing
in the flow shows you what was registered.

You then get back a **Client ID** and **Client Secret** by email from the Lever team. There is no console to re-read
them in — treat the secret as shown once and store it immediately.

**The flow itself**, once you hold credentials (production hosts shown; swap in the sandbox hosts from §5 while
building):

- Authorize: `GET https://auth.lever.co/authorize` with `client_id`, `redirect_uri`, `response_type=code`, `state`,
  `scope` (space-separated) and **`audience`** — Lever documents all six, including `state` and `audience`, as
  **required**. PKCE is not part of the documented flow.
- Exchange: `POST https://auth.lever.co/oauth/token`, `content-type: application/x-www-form-urlencoded`, body
  carrying `grant_type=authorization_code`, `client_id`, `client_secret`, `code` and `redirect_uri`. Client
  credentials go in the **body**, not an HTTP Basic header.
- Response: `{ access_token, refresh_token, token_type: "Bearer", scope, expires_in }`.
- Call the API with `Authorization: Bearer <access_token>` against `https://api.lever.co/v1/`.
- Refresh: same token endpoint, `grant_type=refresh_token` plus `client_id`, `client_secret`, `refresh_token`.

**Lifetimes, and the one that bites:**

| Token | TTL | What breaks |
| --- | --- | --- |
| Access token | **1 hour** (`expires_in: 3600`) | Routine; refresh proactively |
| Refresh token | **1 year, or 90 days of inactivity**, whichever comes first — and **a new refresh token is returned on every refresh** | A connection nobody touches for a quarter is dead and the customer must re-authorize. Refresh on a schedule, not lazily |

**Store the new refresh token from every refresh response.** Lever's docs say the refresh returns a fresh
`refresh_token`, and the example even shows a different token format (`v1.…`) coming back from refresh than from the
initial exchange. A client that keeps replaying the original will work once and then stop.

**Do not send `prompt=consent`.** Lever removed it from the documented flow in June 2024 because forcing consent on an
already-authorized app **blocked non-admin Microsoft 365 SSO users from authorizing at all**. Consent is now requested
only when the app is newly authorized, re-authorized after revocation, or asking for new scopes.

### Path B — Customer-created Data API key

This is what a customer does in their own account, and the only path open without a partnership:

1. A **Super Admin** goes to **Settings → Integrations and API → API Credentials**.
2. Under **Lever API credentials**, click **Generate New Key**.
3. Tick the read and write **endpoints** the integration needs — the key's permissions are fixed by these choices.
4. If the integration must see confidential postings, opportunities or requisitions, enable **"Allow access to
   confidential"** — Lever documents this as grantable **only at key creation**. A key created without it can never be
   upgraded; you regenerate.
5. **Copy the key now.** Lever states this is the one and only time it is shown.
6. Use it as HTTP Basic with the key as the **username and an empty password** — so the header is Base64 of `KEY:`.
   The trailing colon is not optional, and omitting it is a classic silent 401.

Multiple keys can be active at once, which is the sane way to give each integration its own revocable credential.

## 5. Callback URLs, environments and the `audience` parameter

Register **every** callback host in your registration submission. Lever's FAQ says you may register multiple
callbacks, that they are registered against the app rather than per customer, and that the `redirect_uri` you send
must match a registered value. Lever also notes you may register with one callback and request additional ones through
support — an email each time, so get the list right on day one. For Unified.to these are one per data centre; confirm
the current list with the platform owner rather than assuming:

```
https://api.unified.to/oauth/code          # us (default)
https://api-eu.unified.to/oauth/code       # eu
https://api-au.unified.to/oauth/code       # au
https://api-dev.unified.to/oauth/code      # dev
```

**Sandbox and production are two separate apps.** Lever's FAQ is explicit: callbacks can be unique to sandbox and
production, because "you will have two separate apps, one for each environment, and the configuration can be
different." During development on sandbox, callbacks may be plain `http`. Nothing about a working sandbox app implies
anything about production — different client ID, different secret, different auth server, different API host:

| | Authorize / token host | API base | `audience` |
| --- | --- | --- | --- |
| **Production** | `https://auth.lever.co` | `https://api.lever.co/v1/` | `https://api.lever.co/v1/` |
| **Sandbox** | `https://sandbox-lever.auth0.com` | `https://api.sandbox.lever.co/v1/` | `https://api.sandbox.lever.co/v1/` |
| **EU** | see Platform state — **verify with Lever** | `https://api.eu.lever.co/v1/` | `https://api.eu.lever.co/v1/` |

**The `audience` parameter is the single most expensive thing to get wrong.** It is required, it must be the API base
URL, and Lever stresses that it **must end in a trailing slash**. Omit it or malform it and the authorization does not
fail loudly: the customer sees a consent screen granting **only `offline_access`**, authorizes happily, and every
subsequent API call is forbidden. Lever's own debugging table lists exactly this symptom. Note also Lever's warning
that their Postman template works only against sandbox, precisely because it does not send `audience`.

## 6. Scopes — and the permission rule that outranks them

Lever scopes are space-separated in the authorize URL and shaped `<resource>:<action>:admin` —
`opportunities:read:admin`, `postings:write:admin`, `interviews:read:admin`, `files:write:admin`,
`webhooks:write:admin`, and so on across roughly fifty documented strings. Plus `offline_access`, which is not a
resource at all: **include it or you get no refresh token.**

Rules that change what you should request:

- **A write scope contains its read scope.** Lever: "Write:admin scopes include all Read:admin endpoints." Requesting
  both `contact:read:admin` and `contact:write:admin` is redundant, and Lever's debugging guide notes that when both
  are registered **only the write scope is included** — which can make a `scope` response look like it lost a value.
  Request the write scope alone for a resource you write.
- **Formatting is unforgiving.** A single space between scopes; no commas, no leading or trailing whitespace.
- **Scopes must be registered on the auth server before you can request them.** Asking for a scope your app was not
  registered with fails at authorize time; adding one is a request to Lever, not a config change — and adding a scope
  later means existing customers must re-authorize to gain it.
- **Budget 5–8, cap 20.** Lever states both numbers. A maximal scope list is not free: it is what the customer's
  Super Admin reads on the consent screen.
- **Confidential data needs `confidential:access:admin`**, and it is a separate scope from the resource scopes. On the
  API-key path the equivalent is a toggle set at key-creation time only (§4 Path B).

**The rule that outranks all of the above: a Lever Super Admin must be the one who authorizes.** Lever's OAuth page
says Super Admins "will authenticate your app on behalf of their whole organization," and the same page is where they
later see your app — rendered with the logo you submitted — and revoke it. A perfectly scoped app pointed at a
non-admin user does not connect. Lever's documented meaning for **403** on the Data API is the same idea from the
other side: "Your Lever account settings don't authorize you to perform the requested operation. Talk to a Super
Admin on your Lever account to update your API settings."

## 7. Rate limits, plan gates, confidential data, listing

- **Rate limits are a token bucket, per API key**, with **no per-endpoint limits**: a steady state of **10
  requests/second**, bursting to **20 requests/second** when Lever can allow it. Lever says explicitly that these
  defaults are **not guaranteed**, vary with server load, and may change — so implement **exponential backoff** on
  `429` rather than pacing to a hardcoded number.
- **Plan gates exist and are invisible from your side.** Requisitions endpoints require the customer to have the
  Lever TRM Enterprise package or the Advanced HR feature. Older API-key integrations and manual webhooks require the
  Data API and Webhook features respectively. OAuth integrations with programmatic webhooks are, per Lever, available
  to all customers.
- **Confidential objects are invisible without explicit access.** Postings, opportunities and requisitions can be
  marked confidential; without confidential access, requests for them return an access error rather than an empty
  result you could mistake for "this customer has none."
- **Pagination is cursor-based**: list responses carry `data`, `next` and `hasNext`; pass `next` back as `offset`.
  `limit` ranges 1–100, defaulting to 100. Only an offset Lever gave you is valid.
- **Listing** happens in the Lever marketplace (`marketplace.lever.co`) after the QA review. Your integration is
  listed as *coming soon* once it works end to end against your help-centre article, and flipped to *available* only
  when you confirm production is live.

## 8. Verify end-to-end

Do not stop at "the token came back."

1. Authorize through your platform's real connect flow against a **second** Lever account — a sandbox tenant, or a
   mutual customer's — not the one that built the integration.
2. **Read the consent screen.** If it lists only `offline_access`, your `audience` is missing or malformed (§5). This
   is the check that catches the most common Lever failure, and it takes five seconds.
3. Confirm the token response carries a **`refresh_token`**, and that `scope` lists what you expected — remembering
   that a write scope swallows its read twin (§6).
4. Make one real read against the right host for the environment. A sandbox client ID against the production API, or
   the reverse, produces signing-key errors rather than an honest 401 (§5).
5. **Refresh, then refresh again using the token returned by the first refresh.** Two minutes of work for a failure
   that otherwise appears a day later.
6. Repeat step 4 as a **non-Super-Admin** user if any customer might connect as one. Expect failure, and design for it.
7. Exercise pagination past the first page, with an offset Lever actually returned.

| Symptom | Cause |
| --- | --- |
| Consent screen shows only `offline_access` | `audience` missing or not ending in a trailing slash (§5) |
| Redirect window shows `undefined` | A parameter in the authorize URL does not match the registration — usually the callback URI (§5) |
| `403 … Error: ClientID not found` | Wrong auth host for the environment (sandbox client against `auth.lever.co`, or the reverse) (§5) |
| `403 … Unable to find a signing key that matches` | Calls going to the wrong API host for the environment (§5) |
| `401 Unauthorized` right after registration | Client **secret** field populated with the client ID/key instead of the secret (§4) |
| `403 … The key you provided does not have access to this endpoint` | Scope not requested, not registered, or shadowed by its write twin (§6) |
| Scope list comes back shorter than requested | Read scope de-duplicated into the write scope — expected (§6) |
| Authorize rejected for one customer only | The authorizing user is not a Super Admin (§6) |
| 403 on the Data API for one customer | Their Lever account settings / API permissions — a Super Admin must change them (§6) |
| Second refresh fails, first succeeded | Client is not storing the rotated refresh token (§4) |
| Connection dies after a quiet quarter | 90-day inactivity expiry on the refresh token (§4) |
| Sandbox works, production 401s | Separate apps, separate credentials, separate hosts (§5) |
| Requisition endpoints 403 for some customers | Plan gate: TRM Enterprise or Advanced HR (§7) |
| Confidential postings missing, no error on the list call | Confidential access not granted at credential creation (§4 Path B, §7) |
| `429` under normal load | 10 req/s steady, 20 burst, per key; back off exponentially (§7) |
| Non-admin Microsoft 365 SSO users cannot authorize | Client still sending `prompt=consent` (§4) |

## 9. Hand off — never commit the key

- **Do not** write a client secret or API key into source control, a test, a fixture, a committed `.env`, a ticket, a
  PR body or a chat channel. Values go to the human running this, for their secret store or console. The Postings API
  needs no credential at all and its site name may be recorded freely — keep the two apart in your head.
- If a code change is needed (a callback host, a scope string, the `audience` value), keep it secret-free and say
  plainly what the human must set out of band.
- Report a secret once so it can be pasted into the secret store, say clearly that it is now in the transcript and can
  be rotated, then move on.
- Close with: which credential model you ended on; the client ID (or which customer holds which key); where the secret
  was delivered; the environment and its full host triplet — authorize, token, API base — and the exact `audience`
  string; the scope strings requested; the Super Admin requirement to pass to customers; the refresh cadence the
  90-day inactivity window demands; and whatever is still waiting on Lever.

## Stop and ask

Hand back to a human rather than guessing when: **there is no Lever partnership** and the ask is OAuth credentials
(say so in the first reply — do not start a registration that cannot complete); the partner form, agreement or QA
review needs business, security or compliance claims; someone proposes re-issuing partner credentials on a live
integration (that re-authorizes every customer); a scope request comes back refused; the target is **EU customers**
and the auth host question in Platform state is unresolved; a customer cannot find the API Credentials tab (they are
not a Super Admin); confidential-data access is needed on a key that already exists (it cannot be added after
creation); or the developer pages no longer match the Platform state section above.

Note also that this skill was written without browser automation: every fact here came from fetching Lever's public
documentation and probing its hosts directly. A run that also has no browser should hand click paths and form content
to the user rather than simulating a portal session.

## References

Verified to return HTTP 200 on 2026-09-20.

- Lever API overview, authentication, scopes, rate limits, pagination — https://hire.lever.co/developer/documentation
- OAuth for partner product integrations (registration inputs, FAQ, debugging table) — https://hire.lever.co/developer/oauth
- Partner product integration process (the four steps) — https://hire.lever.co/developer/partner
- Developer FAQ (Postings API vs Lever API, how to get an API key) — https://hire.lever.co/developer/support
- API changelog / updates (incl. the `prompt=consent` removal) — https://hire.lever.co/developer/updates
- Use cases — https://hire.lever.co/developer/usecases
- Deprecated objects (candidates vs opportunities vs contacts) — https://hire.lever.co/developer/deprecated
- Developer home — https://hire.lever.co/developer
- Sandbox copy of the API docs (sandbox hosts and audience) — https://hire.sandbox.lever.co/developer/documentation
- Sandbox copy of the OAuth page — https://hire.sandbox.lever.co/developer/oauth
- Sandbox copy of the partner page — https://hire.sandbox.lever.co/developer/partner
- EU copy of the API docs (EU hosts — see Platform state) — https://hire.eu.lever.co/developer/documentation
- Generating and using API credentials (customer-side key creation) — https://help.lever.co/s/article/Generating-and-using-API-credentials
- Using Lever's XML job posting feed (Postings API feed mode) — https://help.lever.co/s/article/Using-Lever-s-XML-job-posting-feed
- Lever career site options — https://help.lever.co/s/article/Lever-Career-Site-Options
- Lever support contact — https://help.lever.co/s/contactsupport
- Become an integration partner (interest form) — https://www.lever.co/partnershipinterest
- Lever partners overview — https://www.lever.co/partners
- Partner marketplace / ecosystem — https://marketplace.lever.co/
- Postings API, live example (public, unauthenticated) — https://api.lever.co/v0/postings/lever

Lever's OAuth and Partner pages also link an **Integrator Resources** repository on GitHub (example app and Postman
collection) at `github.com/lever/integrator-resources`. It could not be reached from this session — GitHub access was
blocked by session policy, not by Lever — so it is named here rather than listed as verified.
