Docs / Shared / Acceptable use

Acceptable use

What you may do with the data you pull, how long you may keep it, and the one thing we ask you to pass on.

Plain language, not a contract, and short enough to read once. If something here conflicts with a signed agreement, the agreement wins. If something is not covered, ask — we would much rather answer than have you guess.

What you may build

Anything you want, for your own users. Job boards, aggregators, alerting, dashboards, matching, analysis, models, internal tools — that is what the API is for, and none of it needs permission beyond a key.

Show the data, transform it, combine it with your own, charge for the product you build on it. The plan you are on is the limit, and it is a request limit rather than a use limit.

What you may not do: resell the corpus as data

The one line: build products on the data, do not resell the data itself.

Concretely, without asking us first, do not republish the corpus in bulk — as a dataset, a dump, a feed, a scrape target, or an API of your own that hands the records on. The difference is who the records are for. Serving a posting to a jobseeker who searched for it is the product working. Handing another company the whole set so they can serve it is not, and the request quota does not distinguish the two: a full walk of the jobs corpus is a low four-figure number of requests, which is a rounding error inside a Scale month of 250,000.

This is not us being precious about volume. Almost all of this data is aggregated from other people's sites under a crawling relationship we have to keep working, and a copy of it circulating with no link back to us is a copy we cannot correct, cannot suppress, and cannot answer for.

If bulk redistribution is your use case, that is a conversation and not a refusal — say so and we will work out terms.

Caching and how long you may keep it

Cache freely. Mirror the whole thing if you like — updated_after exists precisely so you can, and polling it is cheaper for both of us than re-walking collections.

Two rules on what you hold:

A cached record is a snapshot, not a subscription to the truth. A posting can be corrected, retired or removed after you pulled it, and the sections below are about the third case.

Attribution: keep the link

We do not ask you to credit softon. We do ask one thing, and it is for the sites the data came from rather than for us:

When you show a posting to a person, keep url reachable from it. Do not strip it, and do not present a posting as originating with you when the source field says otherwise. A link back is the whole basis on which the sites we read tolerate being read.

Inside your own systems — analysis, models, matching, anything a person does not read as a listing — this does not apply.

Takedowns, and an honest gap

Employers and individuals can ask us to remove a posting, a company, or an entire source. When they do, we suppress it and it leaves every response, including the archive.

What we ask of you: if we tell you a record has been removed, remove it too, and do it promptly. If the request reaches you first — an employer emails you about a posting you got from us — tell us, because a removal that only happens in your copy leaves it live in everyone else's.

How to find out that something was removed

Re-fetch the id. A removed record answers 410 Gone. The id below is illustrative — there is deliberately no real removed id printed here, because publishing one would be publishing which posting somebody asked to have taken down.

GET /v1/jobs/djinni:000000000

410 Gone
{
  "data": null,
  "error": {
    "code": "gone",
    "message": "this job was removed at the request of the employer or the
                individual concerned; stop serving any copy you hold"
  }
}

Three outcomes and they mean different things, so branch on all three:

ResponseWhat happenedWhat to do
200 with "active": falseThe source stopped publishing itYour call — it is still real data, just not a live vacancy
410 goneSomeone asked us to remove itDelete your copy. It is not coming back
404 not_foundNo such id here, and there never wasCheck the id

Now the limit, because you should not find it out the hard way. A removal does not appear in your incremental feed. Suppression takes the record out of every response rather than marking it, so unlike a retired posting — which stays queryable with active: false and a deactivated_at that updated_after matches — nothing in the updated_after stream will ever mention it. The 410 is something you have to go and ask for.

So if you mirror the corpus, re-check ids on a cycle you are comfortable with. There is deliberately no endpoint listing what has been removed: that list is the one thing here we will not publish, because it would answer "who asked to disappear" to anyone with a key. A tombstone you can only see by naming an id you already hold is the most we can give you, and it is why 410 is returned only for ids this platform actually had — an id that was never here is still a 404.

Availability, in the plainest terms

There is no SLA. Not "an SLA we have not published" — there is not one, and this page is not the place to imply otherwise.

What is actually true: the API is a small stack on a single box, the scrape schedule is published and best-effort, and it runs on cron rather than anything with a guarantee attached. Sources block us, change their markup, and go down. We watch it and we fix it, and that is a commitment of attention rather than of uptime.

So: build a client that tolerates a request failing and a source going quiet for a day. Pagination & errors covers the retry behaviour worth having. If you need a guarantee in writing before you can depend on this, tell us what you need — that is a real conversation and the answer might be yes.

The short list of things that get a key revoked

Everything on that list gets a message before it gets an action, except a key that is actively leaking — that we rotate first and explain after.