> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ichabod.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Organization tools

> Tools scoped to Organization profiles: roles, Seeker search, interest, unlocks, and credits.

Calling these with a Seeker key returns `forbidden`. See also the [shared tools](/tools/shared) (`get_profile`, `update_profile`, `list_matches`, `get_rate_limits`, `ping`).

## post\_role

Post a new open role. **Charges 5 credits (\$5)** from your [credit balance](/concepts/credits); fails with `insufficient_balance` (and charges nothing) if the balance is short. The role expires 30 days after posting.

```json theme={null}
{
  "id": "…", "organization_id": "…",
  "name": "Horseman (headless)", "description": "…",
  "what_we_are_looking_for": "…",
  "location": "Sleepy Hollow, NY", "model": "in-person",
  "status": "open",
  "posted_at": "2026-06-10T12:00:00.000Z", "expires_at": "2026-07-10T12:00:00.000Z"
}
```

*Rate limits: role\_write (20/day, shared with `update_role`).*

***

## update\_role

Edit fields of an **open** role you own. Omitted fields unchanged; same field rules as `post_role`. Editing is free.

Returns the updated role.

*Rate limits: role\_write (20/day, shared with `post_role`).*

***

## close\_role

Close an open role you own. It leaves search and the public index, and its matches drop from both sides' lists. Paid [unlocks survive](/concepts/role-lifecycle). Irreversible — reopening means a fresh `post_role`.

```json theme={null}
{ "id": "…", "status": "closed" }
```

*Rate limits: burst only.*

***

## list\_my\_roles

All roles you've posted — open, closed, and expired — newest first. No inputs. Returns an array of role objects (same shape as `post_role`'s result). Watch `expires_at` here for repost planning.

*Rate limits: read (200/hour).*

***

## search\_seekers

Search Seeker profiles with a freeform keyword query, matched across name, tagline, experience, and what's-next blobs. `contact_email` is never returned here — unlock the Seeker, then read it from [`get_profile`](/tools/shared#get_profile). Omit `query` to browse the most recently joined Seekers.

```json theme={null}
[
  {
    "id": "…", "handle": "crane", "name": "Ichabod Crane",
    "tagline": "Schoolmaster turned solo operator. Teaches, ships, and out-eats any room.",
    "experience": "…", "what_is_next": "…",
    "website": "https://…", "created_at": "…", "last_edited_at": "…"
  }
]
```

*Rate limits: search (100/hour).*

***

## get\_seeker

A Seeker's full profile, by `seeker_id` or `@handle` (with or without the leading `@` — provide exactly one of the two). `contact_email` is included **only if you have unlocked this Seeker** — otherwise `null`.

```json theme={null}
{
  "id": "…", "handle": "crane", "name": "Ichabod Crane",
  "tagline": "…", "experience": "…", "what_is_next": "…",
  "website": "https://…", "created_at": "…", "last_edited_at": "…",
  "contact_email": null
}
```

*Rate limits: read (200/hour).*

***

## express\_interest\_in\_seeker

Express interest in a Seeker (by `seeker_id` or `@handle`) **for one of your open roles**. Interest is always role-scoped. **Idempotent**.

```json theme={null}
{ "id": "…", "seeker_id": "…", "role_id": "…", "side": "Organization", "created_at": "…" }
```

The Seeker sees this immediately in their interested-Organizations list; if they reciprocate, it becomes a [match](/concepts/interest-and-matches).

*Rate limits: express\_interest\_in\_seeker (50/day **per role**).*

***

## withdraw\_interest\_in\_seeker

Withdraw your Organization's interest in a Seeker (by `seeker_id` or `@handle`) for one of your roles. If the Seeker had expressed interest back, the [match](/concepts/interest-and-matches) dissolves for both of you; the Seeker's interest is untouched, so re-expressing interest re-forms the match. A paid [unlock](/concepts/interest-and-matches#contact-unlocks) is unaffected — it survives. Returns `not_found` if you had no interest in that Seeker for that role.

<ParamField body="seeker_id" type="string (uuid)">Provide exactly one of `seeker_id` or `handle`.</ParamField>
<ParamField body="handle" type="string">The Seeker's public `@handle`, with or without the leading `@`. Provide exactly one of `seeker_id` or `handle`.</ParamField>
<ParamField body="role_id" type="string (uuid)" required>Must be an open role you own.</ParamField>

```json theme={null}
{ "withdrawn": true, "seeker_id": "…", "role_id": "…", "match_removed": false }
```

*Rate limits: withdraw\_interest\_in\_seeker (30/day).*

***

## list\_interested\_seekers

Seekers who have expressed interest in one of your roles, as profile summaries. Newest first.

```json theme={null}
[
  {
    "interest_id": "…", "interested_at": "2026-06-09T10:00:00.000Z",
    "seeker_id": "…", "handle": "crane", "name": "Ichabod Crane",
    "tagline": "…", "experience": "…", "what_is_next": "…",
    "website": null, "created_at": "…", "last_edited_at": "…"
  }
]
```

*Rate limits: list (60/hour).*

***

## list\_seeker\_interests

The Seekers **you** have expressed interest in — your outbound pipeline — as profile summaries, each tagged with the role it was expressed for and a `status` of `matched` (the Seeker reciprocated) or `pending`. Only interests on your currently open roles. Newest first.

<ParamField body="role_id" type="string (uuid)">Optional. Filter to a single one of your open roles; `not_found` if it isn't an open role you own.</ParamField>

```json theme={null}
[
  {
    "interest_id": "…", "interested_at": "2026-06-09T10:00:00.000Z",
    "status": "pending",
    "role_id": "…", "role_name": "Horseman (headless)",
    "seeker_id": "…", "handle": "crane", "name": "Ichabod Crane",
    "tagline": "…", "experience": "…", "what_is_next": "…",
    "website": null, "created_at": "…", "last_edited_at": "…"
  }
]
```

Use this to see who you've already pursued and avoid duplicate outreach. `contact_email` is never included here; unlock a matched Seeker to reveal it.

*Rate limits: list (60/hour).*

***

## unlock\_seeker

Unlock a matched Seeker's contact email, by `seeker_id` or `@handle` (provide exactly one of the two). **Charges 1 credit (\$1)**, once, permanently — see [unlocks](/concepts/interest-and-matches#contact-unlocks). Requires a current mutual match on at least one open role (`not_found` otherwise). **Idempotent** — re-calling returns the existing unlock without charging. Seekers are not notified.

```json theme={null}
{
  "id": "…", "organization_id": "…", "seeker_id": "…",
  "credits_spent": 1, "unlocked_at": "2026-06-10T12:00:00.000Z"
}
```

After this, `get_profile` for that Seeker includes their `contact_email`.

*Rate limits: unlock\_seeker (20/day).*

***

## get\_credit\_balance

Your current credit balance in credits (1 credit = \$1). A new Organization starts at `{ "balance": 20 }` from the [Early Access welcome grant](/concepts/credits#starting-balance); it reads `0` once that's spent and nothing has been purchased. Top up via the [dashboard](https://ichabod.dev/account). No inputs.

```json theme={null}
{ "balance": 19 }
```

*Rate limits: read (200/hour).*
