# Agent quickstart

> What prompt do I paste into my coding agent to integrate BetterJobs?

Source: https://docs.betterjobs.cc/agents/agent-quickstart/

Paste the prompt below into Claude Code, Cursor, or any coding agent that can read files and fetch URLs. It points the agent at the docs and the spec, and lists the traps it must handle.

1. Set your key where the agent’s shell and your app can read it. A `bj_test_` key is enough while you build. See [Authentication](https://docs.betterjobs.cc/getting-started/authentication.md).

   ```bash
   export BETTERJOBS_API_KEY="bj_test_..."
   ```

2. Open your repo in the agent and paste this prompt.

   Prompt

   ```text
   Integrate the BetterJobs job-data API into this repository.


   Context
   - BetterJobs sends one job search to several job-data providers plus its own index,
     merges duplicates and returns canonical jobs. 1 credit per unique job returned.
   - Docs index: https://docs.betterjobs.cc/llms.txt. Follow its "Rules for AI agents".
   - Exact contract: https://docs.betterjobs.cc/openapi.yaml. Use its field names, paths and error codes
     verbatim. Do not guess fields. Fetch the .md version of any docs page you need:
     Replace the trailing / of a docs URL with .md (e.g. /concepts/waterfall/ → /concepts/waterfall.md). API reference pages under /api/ have no Markdown twin; read /openapi.yaml instead.


   Requirements
   1. Put the client in one module that matches this repo's existing structure and
      HTTP library. No new dependencies unless the repo has no HTTP client.
   2. Read the key from the BETTERJOBS_API_KEY environment variable. Fail at startup if
      it is not set. Never hard-code a key, never log it, never send it to a browser.
      Add BETTERJOBS_API_KEY to the repo's env example file with an empty value.
   3. Base URL https://api.betterjobs.cc/v1. Send on every request:
      Authorization: Bearer <key>
      BetterJobs-Version: 2026-10-01
   4. Implement searchJobs(filters, options) on POST /jobs/search:
      - Always set waterfall.max_credits. Expose it as a required argument.
      - Support dry_run: true (free estimate). Call it first when a search may cost more
        than 50 credits.
      - Page with next_cursor until it is null or the caller's limit is reached.
      - Send a fresh Idempotency-Key (UUID) per logical request and reuse it on retries.
   5. Handle results correctly:
      - metadata.status "partial" is a success. Log metadata.providers.failed; do not retry
        the whole search.
      - Deduplicate and store jobs by their canonical id. Re-reading a paid job is free.
      - null means unknown, [] means verified none. Never coerce null to false or 0.
   6. Handle errors by error.code, not by message text:
      - rate_limited: wait Retry-After seconds, then retry.
      - internal_error: retry with the same Idempotency-Key and backoff.
      - unknown_filter / invalid_request: raise with error.param. Do not retry.
      - insufficient_credits / plan_required: raise with upgrade_url. Do not retry.
      Log X-Request-Id on every failure.
   7. Tests: use the keyless sandbox https://api.betterjobs.cc/v1/sandbox/jobs/search (no auth, fixed
      illustrative data, nothing charged) or a bj_test_ key. Never call the API with
      a bj_live_ key in tests.
   8. Run the repo's existing lint, type check and tests. Then show me the diff and one
      example call I can run.
   ```

3. Review the diff. Check the list below before you merge.

4. Swap in a `bj_live_` key in production.

> Agents guess field names
>
> Models trained on other job APIs often write `job_title` or `company_domain` from memory. BetterJobs rejects unknown filter fields with `400 unknown_filter`, so the bug shows up at once. The prompt tells the agent to read the spec instead.

## Review checklist

- [ ] The key comes from `BETTERJOBS_API_KEY` and the app fails at startup without it.
- [ ] Every request sends `BetterJobs-Version: 2026-10-01`.
- [ ] Every search sets `waterfall.max_credits`.
- [ ] Large searches call `dry_run: true` first.
- [ ] `metadata.status: partial` is treated as success.
- [ ] Jobs are stored by canonical `id`.
- [ ] `null` is never turned into `false`, `0` or an empty string.
- [ ] Errors branch on `error.code`. `rate_limited` honours `Retry-After`.
- [ ] Retries reuse the same `Idempotency-Key`.
- [ ] Tests never use a `bj_live_` key.

Each item links back to one page: [The waterfall](https://docs.betterjobs.cc/concepts/waterfall.md), [Canonical jobs](https://docs.betterjobs.cc/concepts/canonical-jobs.md), [Errors](https://docs.betterjobs.cc/platform/errors.md), [Idempotency](https://docs.betterjobs.cc/platform/idempotency.md), [Rate limits](https://docs.betterjobs.cc/platform/rate-limits.md), [Versioning](https://docs.betterjobs.cc/platform/versioning.md).

## Let the agent use BetterJobs live

The prompt writes code that calls the API. If you also want the agent itself to search jobs or check companies while it works, connect the [MCP server](https://docs.betterjobs.cc/agents/mcp-server.md). Its tools carry credit costs and follow the same consent rule.

## Related

- [llms.txt and Markdown](https://docs.betterjobs.cc/agents/llms-txt.md)
- [Quickstart](https://docs.betterjobs.cc/getting-started/quickstart.md)
- [OpenAPI and SDKs](https://docs.betterjobs.cc/platform/openapi-and-sdks.md)
