Metadata-Version: 2.4
Name: countersignatory
Version: 0.1.0
Summary: The going rate for a human minute. A standard-library client for the Countersignatory quote API and Spot Index.
Project-URL: Homepage, https://countersignatory.com
Project-URL: Methodology, https://countersignatory.com/methodology
Author-email: Countersignatory Ltd <douglas@countersignatory.com>
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agents,countersignatory,human-in-the-loop,pricing,spot-index,verification
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# countersignatory

The going rate for a human minute. A Python client for the Countersignatory quote API and Spot Index. Standard library only, Python 3.9 and later.

**Nothing is fulfilled yet.** Every price is an indicative quote, not a binding offer. No task is taken, no work is done and no money moves.

## Quickstart

```python
import countersignatory as cs

q = cs.quote(task="judgment", tier="consensus", n=3, sla=3600, max_price=5)
print(q.unit_price, q.band, q.would_clear, q.quote_id)

cs.interest(q, would_pay=True, note="labelling 200 eval rows a week")  # this price would clear
cs.index()                                                           # the Spot Index
cs.market("countersign.certified_translation")                       # one market from it
cs.interest(market="countersign.certified_translation", would_pay=True)  # vote to open a market
```

Arguments map one-to-one onto `POST /v1/quotes`: `task` is `task_type`, `sla` is `sla_seconds`, `n` is `consensus_n`, `market` is `market_id`, and `max_price`, `jurisdiction`, `unassisted` and `criteria` keep their names. The quote comes back exactly as the API sent it: every field is an attribute, `q.derived` carries what is derived rather than measured, and `q.raw` is the whole response. Nothing is rounded.

## Keys

A key is free, instant and needs no approval. The client looks for one in this order:

1. `key=` on the call.
2. `COUNTERSIGNATORY_KEY` in the environment.
3. The cached file `~/.config/countersignatory/key` (`%APPDATA%\countersignatory\key` on Windows), mode 0600.
4. In CI (`CI`, `GITHUB_ACTIONS`, `GITLAB_CI`, `BUILDKITE`, `CIRCLECI` or `JENKINS_URL` set), it stops with `KeyRequired`. It never issues a key in CI, because every ephemeral runner would mint a new one. Set `COUNTERSIGNATORY_KEY` in your CI secrets.
5. Otherwise it takes a key with `POST /v1/keys`, caches it and prints one line to stderr saying where.

`index()` and `market()` need no key.

## Errors

Nothing is retried and nothing is substituted. An error from the API is raised as `CountersignatoryError` with `.code`, `.message`, `.status` and `.body`. Quoting a market that is listed but not open raises `MarketNotOpen`, whose message carries the one line that registers interest in it. A key that is not in the shape the API issues raises `InvalidKey`.

## What it sends

Each request carries `x-countersignatory-client: python/0.1.0`, so calls from this client can be counted as a channel. That header is the only telemetry. Nothing is sent on import.

Set `COUNTERSIGNATORY_BASE_URL` to point the client somewhere other than `https://countersignatory.com`.

## Markets

<!-- prices:start -->
Indicative prices from the Spot Index, index version `seed-2026-09-23b`, read when this package was built. They are seeded from third-party comparables, not live clears, and do not update with the package. Call `index()` for the current figures and `/methodology` for how each one is derived.

| Market | Tier | State | Indicative base (USD) | Band | Unit |
|---|---|---|---|---|---|
| `check.general` | check | open | $0.80 | $0.50 to $1.50 | per task |
| `consensus.3.general` | consensus | open | $3.50 | $2.60 to $5.00 | per task |
| `consensus.5.general` | consensus | open | $5.60 | $4.20 to $8.00 | per task |
| `countersign.domain_expert` | countersign | open | $18.00 | $12.00 to $30.00 | per attestation |
| `countersign.uk_professional` | countersign | open | $25.00 | $15.00 to $40.00 | per attestation |
| `countersign.accessibility_statement` | countersign | opening | $21.00 | $14.00 to $28.00 | per criterion (MED shown) |
| `countersign.certified_translation` | countersign | opening | $16.00 | $12.00 to $24.00 | per page (250 words) |
| `seal.notarisation_us` | seal | open | $45.00 | $38.00 to $60.00 | per seal |

A market in the `opening` state is listed with a reference rate but takes no quotes yet. Quoting it raises `market_not_open`; registering interest is the vote that opens it.
<!-- prices:end -->

Methodology: https://countersignatory.com/methodology

MIT licence. Countersignatory Ltd.
