For the complete documentation index, see llms.txt. This page is also available as Markdown.

API Reference

Practical guidance for working with the API in production


1. Parsing the Response Correctly

This is the most critical thing to get right. The API response is not a simple array of job objects.

The Problem

The API returns a top-level JSON array that contains mixed types — typically two strings followed by the actual jobs array:

["string_value", "another_string", [{ "title": "...", ... }, { "title": "...", ... }]]

If you naively treat the response as Job[], you'll get strings instead of job objects.

The Solution

Search for the nested array within the root array:

const response = await fetch(url);
const data = await response.json();

if (!Array.isArray(data)) {
  throw new Error('Unexpected response format');
}

// Find the nested array containing job objects
let jobs = data.find(item => Array.isArray(item));

// Fallback: if every element is an object, the root array IS the jobs array
if (!jobs && data.length > 0 && typeof data[0] === 'object' && data[0] !== null) {
  jobs = data;
}

if (!jobs || !Array.isArray(jobs)) {
  throw new Error('Could not locate jobs array in response');
}

Python Equivalent

Do not assume the response structure is stable. The mixed-type root array is the current behaviour, but defensive parsing that searches for the jobs array will survive format changes.


2. Handling HTML in Descriptions

Job descriptions frequently contain raw HTML markup:

Strip HTML for Plain Text

Truncate Long Descriptions

Descriptions can be very long. If you're displaying summaries or working within token limits (e.g., AI/LLM contexts), truncate after stripping:

When to Disable Descriptions

Use show_description=false when:

  • Building a job listing/browse view (titles + companies are enough)

  • Doing an initial scan before fetching details

  • Working within bandwidth or payload size constraints

  • The consumer doesn't need description text (e.g., job count analytics)


3. Caching

The API returns recent job listings that don't change by the second. Caching responses for 5 minutes is a sensible default — it reduces API calls significantly while keeping data fresh enough for most use cases.

Simple In-Memory Cache

Cache Key Strategy

Use the full set of filter parameters as the cache key. Serialise them deterministically:

This ensures that ?tag=solidity&limit=10 and ?tag=solidity&limit=20 are cached separately.

When to Cache More Aggressively

  • Static reference data (like the list of available tags) can be cached indefinitely or for hours

  • Broad, unfiltered queries are expensive and change slowly — cache for 10+ minutes

  • Highly specific queries (tag + country + remote) return smaller datasets that change more often — 5 minutes is appropriate


4. Rate Limiting and Retry Logic

The API enforces rate limits and returns 429 Too Many Requests when exceeded.

Exponential Backoff with Jitter

What to Retry

Error
Retry?
Why

429 Too Many Requests

Yes

Temporary rate limit — will clear

5xx Server Error

Yes

Transient server issues

Network timeout / no response

Yes

Connectivity blip

401 Unauthorized

No

Bad token — retrying won't help

403 Forbidden

No

Permissions issue

4xx (other)

No

Client error — fix the request

Setting
Value
Rationale

Max retries

3

Enough to ride out transient issues without hammering the API

Initial delay

1 second

Gives the rate limiter time to reset

Max delay

10 seconds

Caps wait time to keep UX responsive

Jitter

+/- 20%

Prevents thundering herd if multiple clients retry simultaneously


5. Input Validation

The API silently returns empty results for invalid filter values. Validate on the client side to catch mistakes early.

Validate Tags

Validate Country Slugs

Common Mistakes to Catch

User Input
Problem
Correct Value

"Solidity"

Capitalised

"solidity"

"react developer"

Multi-word phrase

"react"

"web3 marketing"

Multi-word phrase

"marketing"

"USA"

Not a slug

"united-states"

"UK"

Not a slug

"united-kingdom"

"solidty"

Typo

"solidity"


6. Handling Optional Fields

Job objects have inconsistent field presence. Not every job has every field. Always code defensively:

Extra Fields

Job objects may contain fields beyond the documented schema. The API can return additional metadata. Use a pass-through pattern to preserve these:


7. Efficient Multi-Tag Searching

Since the API only supports one tag per request, searching across multiple tags requires parallel requests.

Parallel Fetching with Deduplication

Be mindful of rate limits when making parallel requests. If you're searching across many tags, consider batching with delays between groups.


8. Optimising Payload Size

Full responses with descriptions can be large. Optimise based on your use case:

Scenario

show_description

limit

Why

Job listing page

false

50-100

Titles + companies are enough for browsing

Job detail view

true

1-5

Only fetch descriptions for jobs the user selected

AI agent summary

true

10-20

AI needs descriptions for context, but limit count

Analytics / counting

false

100

Maximise data, minimise bandwidth

Alert / notification

false

10

Quick check for new postings


9. Error Handling Checklist

A robust integration should handle all of these:

  • [ ] 401 — Token is wrong or expired. Surface a clear message pointing to the token page.

  • [ ] 403 — Token permissions issue. Direct user to check their account.

  • [ ] 429 — Rate limit. Implement backoff + retry. Surface a "please wait" message if retry fails.

  • [ ] 5xx — Server down. Retry with backoff. Show cached data if available.

  • [ ] Network error — No response received. Retry, then surface connectivity message.

  • [ ] Empty results — Not an error, but possibly an invalid filter. Suggest checking tag/country spelling.

  • [ ] Unexpected response format — The response shape changed. Log the raw response for debugging.

  • [ ] Missing fields on jobs — Gracefully handle undefined for any field.

  • [ ] HTML in descriptions — Strip or render depending on context.


Compliance with the link-back requirement is mandatory — failure will result in API access suspension.

Rules

  1. Always link to jobs using the apply_url field

  2. Links must be follow links (rel="follow" or no rel attribute)

  3. Never add rel="nofollow", rel="ugc", or rel="sponsored"

  4. Never append tracking parameters (utm_source, utm_medium, ref, etc.) — they're already in the URL

Implementation

Framework-Specific Notes

React / Next.js:

Server-rendered HTML:

For MCP / AI Agent Use Cases

When returning job data through an MCP server or AI agent (where there's no HTML rendering), always include the apply_url in the response so downstream consumers can link correctly. Include a note that the URL must not be modified.


11. Using the RSS XML Endpoint

The API also supports RSS XML responses at a parallel endpoint:

This accepts the same query parameters as the JSON endpoint and returns standard RSS XML. Use cases:

  • Feed readers — subscribe to specific job searches (e.g., ?tag=solidity&remote=true)

  • Zapier / IFTTT / n8n — trigger automations when new jobs match your filters

  • Email digests — pipe the RSS feed into a digest tool for daily/weekly summaries

  • Slack/Discord bots — RSS-to-channel integrations for team job alerts


12. Security Considerations

  • Never commit your API token to version control. Use environment variables.

  • Never log the full request URL in production — it contains your token as a query parameter.

  • Add .env and .env.local to .gitignore if storing tokens in env files.

  • Rotate tokens if you suspect they've been exposed (check web3.career account settings).

  • Your token is for your use only. Do not share it with others or use it across multiple unrelated projects/services.

  • If building a multi-user service, never share tokens between users — each user should authenticate with their own token.

Last updated