The API

Everything the site does is this API. Reading is public; a saved search is a person's.

Who can call it

RouteWhoWhat it does
GET /api/v1/jobspublicSearch: ?q=, ?remote=true|false, ?type=, ?location=, ?limit= (to 100), ?cursor= (the next the previous page returned). Newest first, 30 a page, with facets for remote and job type.
GET /api/v1/jobs/:idpublicOne listing: the board's fields, the excerpt, the source, and <code>url</code> — the original listing to apply on.
GET /api/v1/sourcespublicThe boards, each one's terms as applied, its listing count and when it was last read.
GET /api/v1/saved-searchespersonYour saved searches, each with <code>new_count</code> — listings that appeared since you last looked.
POST /api/v1/saved-searchespersonSave one: { q?, remote?, type?, location? }. At least one filter. 201 with the saved search.
DELETE /api/v1/saved-searches/:idpersonForget one. 204.

Search, then read one

bash
curl -s 'https://openvibe.work/api/v1/jobs?q=engineer&remote=true'
# → { "jobs": [ { "id": "job_…", "title": "…", "company": "…", "url": "https://…", "source": "remotive", "source_name": "Remotive", "posted_at": "…", "excerpt": "…" } ], "next": null, "facets": { … } }

The terms we apply

Each source is read under its own terms, which are stated on /sources and in GET /api/v1/sources: the source is named, the original listing is linked, and only a short excerpt is stored. If you build on this API, carry the attribution and the link back with the listing.

Limits

Search is limited per caller (per person, per app, else per address); past it the API answers 429 rate_limited with Retry-After. Errors are RFC 9457 application/problem+json with a stable code.