TEVOS
● Developer docs · v1

Tevos Developer APIs

Two clean JSON APIs on primary data. The Salary API: ask for a role, level, city tier and country; get back p25 / p50 / p75 / p90 — drawn from 534k+ anonymised comp records, every cell behind a k ≥ 12 anonymity floor. No floor, no number. Silence beats spin. The Company Intelligence API: the live hiring-signal dossier on any tracked company — velocity, momentum, triggers, cities, peers — with zero contact or personal data, by design.

Authentication Salary endpoints Response contract Rate limits Tiers Methodology · k ≥ 12 Live example Company Intelligence API

Authentication

Every /benchmark call needs an API key. Present it as a Bearer token (preferred) or via the X-API-Key header. The coverage and spec endpoints are public. The Company Intelligence API also runs keyless on a small anonymous trial — see its section.

curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://gettevos.com/api/v1/benchmark.php?role=software%20engineer&level=mid&city=Bengaluru&country=IN"

Responses:

StatusMeaning
200Served. If the cohort is below the floor, data is null with a coverage_note — still 200, so you needn't retry.
400Missing the required role parameter.
401API key missing, invalid, or revoked.
429Over your per-minute rate limit (rate_limited) or your monthly quota (quota_exceeded). Honour Retry-After.

Every served call is metered against your key for billing. Keys are issued by invite — request one below.

Salary endpoints

GET/api/v1/benchmark.php API key metered

Salary percentiles for one cell. Resolves your free-text role to a role family and your city to a tier, then runs a 4-tier fallback to find the tightest cohort that clears the floor.

ParamReqNotes
roleyesFree text, e.g. software engineer, data scientist, devops.
levelnoentry·mid·senior·lead·principal, or an integer (years). Default mid.
citynoFree text, resolved to a tier (e.g. Bengaluru → tier-1).
city_tiernoExplicit tier; overrides city. One of tier-1·tier-2·tier-3·metro-us·metro-eu·other.
countrynoISO-2. Default IN (the fully-seeded corpus).
GET/api/v1/coverage.php public cached 1h

The coverage matrix: every (role family × level × city tier × country) cell that clears the k ≥ 12 floor, with its sample size. Check this before spending a metered call so you only ask for cells we can answer.

GET/api/v1/openapi.php public

The full OpenAPI 3.0 spec. Import it into Swagger UI, Postman, or an LLM tool generator.

Response contract

The shape of a populated /benchmark response — INR percentiles are in LPA (lakhs per annum). The numbers below are illustrative placeholders to show the field layout; for real values, fire the live example against the corpus.

{ "role": "software engineer", "role_family": "software_eng", "level": "mid", "city_tier": "tier-1", "country": "IN", "currency": "INR", "period": "annual", "percentiles": { "p25": 12.0, "p50": 18.0, "p75": 28.0, "p90": 42.0 }, "sample_size": 47, "k_floor": 12, "confidence": "high", "fallback_level": "exact", "generated_at": "2026-06-12T12:00:00+00:00", "license": "CC-BY-4.0", "citation": "Tevos Salary API (gettevos.com), CC-BY-4.0" }

When no cohort clears the floor, you get an honest empty — never a guessed number:

{ "role": "...", "level": "...", "city_tier": "...", "country": "IN", "data": null, "percentiles": null, "sample_size": 0, "k_floor": 12, "confidence": "none", "coverage_note": "No cell meets the k ≥ 12 anonymity floor for this query.", "license": "CC-BY-4.0", "citation": "Tevos Salary API (gettevos.com), CC-BY-4.0" }

confidence is high / medium / low / none, and fallback_level tells you how tight the matched cohort was: exact → level_country → role_country → role_only. Attribution is required under CC-BY-4.0 — use the citation string verbatim.

Rate limits

Two limits apply per key. The per-minute limit is a rolling 60-second window — exceed it and you get 429 rate_limited with Retry-After: 60 and X-RateLimit-Limit. The monthly quota is a calendar-month cap (resets on the 1st, UTC); exhaust it and you get 429 quota_exceeded with X-Quota-Limit / X-Quota-Used headers.

Tiers

Sandbox

Free
  • 30 req / min
  • 1,000 req / month
  • CC-BY-4.0 attribution
  • For prototyping

Startup

Invite
  • 120 req / min
  • 50,000 req / month
  • Coverage webhooks
  • Email support

Enterprise

Talk to us
  • Custom rate & quota
  • Bulk / matrix export
  • SLA + priority support
  • Custom cohorts

Pricing and self-serve checkout are rolling out. For now, keys are issued by invite per tier.

Methodology · the k ≥ 12 floor

Percentiles are computed from anonymised compensation bands, grouped into cohorts by role family, seniority level, city tier and country. A cohort is published only when at least twelve distinct contributors sit inside it — the same k ≥ 12 anonymity floor we apply everywhere. Below twelve, the cell is suppressed entirely; we return null, not an estimate. Read the full method on our methodology page.

Live example

Build a request and fire it from your browser. /coverage is public, so it runs with no key. /benchmark needs your key — paste it to see a real response, or leave it blank to watch the 401 contract.

// response will appear here

Company Intelligence API

The company-level hiring-signal dossier: entity resolution, 12-week velocity and momentum, operational triggers (how far a hiring theme over-indexes the market rate, mapped to a service line), top hiring cities, and graph peers where available. All of it derives from primary job-posting data collected continuously from company ATS systems. Zero contact or personal data — this is company-level intelligence, by design, not a people database.

GET/api/v1/company.php Bearer key anon trial 25/day metered

One company per call. Pass a free-text name (resolved through the alias table and entity index) or a directory slug from /companies.php — if both are sent, slug wins.

ParamReqNotes
nameone ofFree text, e.g. zscaler, razorpay, accenture. Alias-resolved to the canonical entity.
slugone ofThe company-directory slug (the /c/<slug>/ path segment). Takes precedence over name.

Authentication & trial

Same key rails as the Salary API: Authorization: Bearer <key> or X-API-Key. Without a key, an anonymous trial serves up to 25 requests per day per IP — enough to evaluate the contract before requesting a key. Keyed calls are metered against your tier's quota and carry X-RateLimit-* headers.

curl "https://gettevos.com/api/v1/company.php?name=zscaler" # anon trial, 25/day curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://gettevos.com/api/v1/company.php?slug=zscaler" # metered, tier limits

Response contract

The values below are illustrative placeholders showing the field layout; fire the live example for real ones. weeks entries are [isoWeek, newRoles] pairs; momentum is clamped ±5 (recent 4-week average vs trailing 12-week median, MAD-scaled) and null with under 6 weeks of history.

{ "query": "zscaler", "entity": { "canonical": "zscaler", "slug": "zscaler", "page": "https://gettevos.com/c/zscaler/" }, "velocity": { "live_roles": 214, "new_30d": 57, "momentum": 3, "weeks": [["2026-W16", 9], ["2026-W17", 12], ["2026-W18", 14]], "momentum_note": "clamped ±5; recent 4-week avg vs trailing 12-week median (MAD-scaled); null = <6 weeks history" }, "triggers": [ { "label": "Cloud security build-out", "service_line": "security engineering", "lift": 2.4, "n": 11, "share": 0.19, "confidence": "high" } ], "trigger_method": "hiring share ≥1.8× corpus baseline, n≥3 roles", "cities": [ { "city": "Bengaluru", "n": 88 }, { "city": "Pune", "n": 41 } ], "peers": ["peer-co-1", "peer-co-2"], "zero_pii": true, "source": "primary job-posting data (company ATS), continuously crawled", "generated_at": "2026-07-01T04:00:00+00:00" }

A company with no live signal in the current corpus returns an honest empty — 200, never a guess:

{ "query": "some company", "entity": null, "data": null, "coverage_note": "No live hiring signal for this company in the current corpus. Tevos tracks companies via their ATS; coverage grows continuously.", "zero_pii": true, "license": "commercial", "generated_at": "2026-07-01T04:00:00+00:00" }
StatusMeaning
200Served — including the honest no-signal shape above.
400missing_param — pass ?name= or ?slug=.
401Key invalid or revoked (keyless callers fall to the anon trial instead).
405Only GET (and CORS preflight OPTIONS) are accepted.
429Anon trial exhausted (25/day) or over your tier's limits. Honour Retry-After.
503Temporary backend issue — retry shortly.

Company API responses are licensed for commercial use under your API terms (not CC-BY). CORS is open (Access-Control-Allow-Origin: *), so it runs straight from the browser.

Live example

Runs keyless on the anonymous trial — no setup at all.

// response will appear here

Request an API key

Keys are issued by invite and work across both APIs. The Company API runs keyless at trial volume; a key lifts you to metered tiers. Tell us what you're building and we'll get you a sandbox key in the next batch.