# Install and connect

## Local Codex or Claude Code

Download https://badal.work/static/badal-recruiter.zip and inspect its contents. Extract the `badal-recruiter` folder into:

- Codex: `~/.agents/skills/badal-recruiter` ([official skill locations](https://developers.openai.com/codex/skills)). Invoke `$badal-recruiter`.
- Claude Code: `~/.claude/skills/badal-recruiter` ([official skill locations](https://code.claude.com/docs/en/skills)). Invoke `/badal-recruiter`.

The bundle needs Python 3.11+ on macOS or Linux, network access to Badal, and a private persistent home directory. A skill installed on one machine is not automatically installed in a cloud runtime. Restart or refresh skill discovery if necessary.

Sign in at https://badal.work/app and open Agent access. Choose one of these local connection methods. Both save the credential only on this machine; neither connects ChatGPT Web.

### One-time link (24-hour access)

Create a connection link in Agent access. In a trusted local Codex or Claude Code conversation where the agent can run this helper and keep its private home directory, the recruiter may paste the link directly into that conversation. The agent should start `badal.py connect` as an interactive terminal process, pass the link to its hidden stdin prompt once, never echo the link or interpolate it into a shell command or argument, and then verify `/api/me`. The link remains in that conversation's history; anyone who can read it before redemption could use it. If the runtime cannot pass the link to the local helper without showing it in a shell command, log, or output, ask the recruiter to use their own terminal's hidden prompt instead.

For the more private terminal route, the recruiter runs this locally (adjust the skill path for Claude Code):

```sh
python3 ~/.agents/skills/badal-recruiter/scripts/badal.py connect
```

Paste the link at the hidden terminal prompt. It is not echoed and must not be entered as a shell argument. Automation may supply it through private stdin. Do not use a literal `echo SECRET` command, browser fetch, web search, or a public/shared prompt containing the link. If there is no private input mechanism, have the recruiter run `connect` themselves.

The link expires after 24 hours and can be redeemed only once. The issued recruiter credential also expires after 24 hours from redemption and can be revoked in Badal. Only the redemption response contains the key; the helper saves it in `~/.config/badal/credentials.json` with mode `0600` in a `0700` directory. The file contains a secret even though the dashboard never reveals it again. Do not attach, print, commit, or read this file into an agent conversation.

### Manual API key (until revoked)

For access that persists across sessions, create a **Manual API key** in Agent access. The key appears once. Have the recruiter run the helper below in their private terminal and paste the key at its hidden prompt. Do not ask them to paste a permanent key into the agent chat, including a private chat: the key does not expire after 24 hours and the conversation may be stored.

```sh
python3 ~/.agents/skills/badal-recruiter/scripts/badal.py connect-key
```

The helper validates the key against Badal before saving it in the same private credential file. A manual key stays valid until the recruiter revokes it in Agent access. Name and revoke old keys there, especially when replacing a device or connection. The key has access to that recruiter's hiring records, so use a separate key for each device or agent environment.

```sh
python3 ~/.agents/skills/badal-recruiter/scripts/badal.py status
python3 ~/.agents/skills/badal-recruiter/scripts/badal.py request GET /api/me
python3 ~/.agents/skills/badal-recruiter/scripts/badal.py request GET /api/campaigns
```

`status` reports local expiry/metadata; only the authenticated account request checks server access. For an approved mutation, save the non-secret request body to a JSON file and use, for example:

```sh
python3 ~/.agents/skills/badal-recruiter/scripts/badal.py request POST /api/campaigns --data-file approved-role.json
```

Use current OpenAPI schemas; never guess field names. The helper permits canonical relative API paths under campaigns, candidates, analytics, jobs, me, assessment-templates, plus integration status and availability. It deliberately cannot manage credentials or initiate Google/OAuth flows. No query strings, arbitrary URLs, redirects, or non-JSON uploads are supported. Use the authorized MCP tools/dashboard for features outside this helper.

## ChatGPT

A ChatGPT workspace that supports skills/plugins can use these instructions in its supported packaging flow. Uploading or pasting instructions alone does not provide authenticated HTTP execution. Connect Badal's remote MCP at `https://badal.work/mcp` using the workspace's OAuth connection interface. Follow https://badal.work/docs#agent and the current [OpenAI plugin authentication guide](https://developers.openai.com/plugins/build/auth). Do not promise a ZIP import is available in every ChatGPT plan or workspace.

A local `127.0.0.1` OAuth callback belongs to the client that initiated it; it cannot be converted to a ChatGPT Web connection by adding an API key to a page. Report a connection failure accurately and stop account mutations until an authenticated `get_account`/`/api/me` succeeds.

## Recovery

- Expired/revoked access: create a fresh connection link and run `connect` again, or use a new manual key with `connect-key`. Revoke an older credential when replacing it.
- Lost redemption response: never blindly retry. The link may have been consumed. Revoke the corresponding connection/key in the dashboard and generate a new link.
- Redirect/network/API error: the helper withholds raw bodies and URLs to avoid credential leaks. Check live documentation and dashboard state. Do not retry a job-creation or decision request until checking whether it already succeeded.
- Permissions error: the credential directory must be private, owned by the local user, and not a symlink. The helper refuses linked or public credential files. Do not weaken permissions to make it run.
