JetScrape supports two authentication methods.
- Session cookie — sent automatically by the browser, or with `-b cookies.txt` /
`Cookie: better-auth.session_token=...` in curl. Used for dashboard work: account, API
keys, payments, subscriptions, notifications, consent.
- API key — sent as an `x-api-key: <key>` header or an `?apiKey=<key>` query parameter.
Used for all programmatic access: scraping, flows, user templates.
Sessions are handled by Better Auth; sign-up, sign-in and social login live under `/api/auth/*`.
Which endpoint expects what
- `/webhook/*` — API key.
- `/flows/*` — API key or session cookie.
- `/user-templates/*` — API key or session cookie.
Sending an API key
curl -X POST https://api.jetscrape.com/webhook/unblocker \
-H "Content-Type: application/json" \
-H "x-api-key: js_abc123xyz..." \
-d '{ "url": "https://example.com", "selectors": [] }'Sending a session
# Sign in and store the cookie
curl -X POST https://api.jetscrape.com/api/auth/sign-in/email \
-H "Content-Type: application/json" \
-c cookies.txt \
-d '{ "email": "you@example.com", "password": "password" }'# Send it back on later requests
curl https://api.jetscrape.com/api/users/session -b cookies.txtReading a 401
Two different 401 bodies exist. Both mean the same thing: the request was not authenticated.
{ "code": "UNAUTHORIZED", "message": "Unauthorized" }{ "statusCode": 401, "message": "Unauthorized", "error": "Unauthorized" }Things to check:
- Are you using the `x-api-key` header rather than `Authorization`?
- Has the key been revoked (`enabled: false`)?
- Has the session expired? Sign in again.
Never ship an API key in client-side code — browser JavaScript, a mobile bundle or a public
repository. Keys carry your credit balance and stay valid until you revoke them.
Create one key per environment. If a key leaks you can revoke just that one without
interrupting anything else.