> For the complete documentation index, see [llms.txt](https://docs.cournot.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cournot.ai/api-reference/partner-public-api.md).

# Partner Public API

## Background

Cournot is an AI-driven oracle for prediction-market resolution. For every market it covers, Cournot produces a final settlement record — verdict, confidence tier, and on-chain proofs — and makes that record publicly auditable by both Partners and end users.

Partners use Cournot as the source of truth for resolving their own markets: once Cournot publishes a verdict, the Partner pulls that record and uses it to settle the corresponding market on their platform.

Two public endpoints support this:

* **`get_public_market`** — anonymous read. Look up a market by `slug` + `source` and return its public record (status / verdict / confidence / proofs / disputes). The primary endpoint Partners call to drive their own resolution.
* **`submit_dispute`** — Partner-authenticated write. If an end user disagrees with a Cournot verdict, the Partner backend can file a dispute on their behalf.

The `source` value is a Partner-specific identifier issued by Cournot at integration time. Each Partner uses its own dedicated value; it is not a public enum.

## Typical integration flow

The primary loop: Partner pulls Cournot's verdict and settles its own market.

```
   Partner backend                                                        Cournot
        │                                                                    │
        │  GET /markets/public?slug=...&source=...                           │
        │ ─────────────────────────────────────────────────────────────────► │
        │ ◄────── { markets:[{ status, verdict, confidence, proofs }] } ──── │
        │                                                                    │
        │  (status = resolved → settle the corresponding Partner market)     │
        │                                                                    │
```

* Poll `get_public_market` for the relevant market. When `status = resolved`, `verdict` / `confidence` / `proofs` are populated.
* Use the returned record to settle the Partner-side market. On-chain `proofs` can be surfaced to end users for auditability.
* No authentication is required for this loop.

## Dispute flow (optional)

If an end user disputes a Cournot verdict, the Partner backend can file the dispute and observe its outcome through the same `get_public_market` endpoint.

```
   end user (Partner)                  Partner backend                    Cournot
        │                                     │                              │
        │   "I disagree with this verdict"    │                              │
        │ ──────────────────────────────────► │                              │
        │                                     │  POST /markets/dispute/      │
        │                                     │       submit                 │
        │                                     │ ───────────────────────────► │
        │                                     │ ◄───── { dispute_id } ────── │
        │                                     │                              │
        │  (later — anyone, no auth)                                         │
        │                                                                    │
        │  GET /markets/public?slug=...&source=...                           │
        │ ─────────────────────────────────────────────────────────────────► │
        │ ◄────── { markets:[{ ..., disputes:[{ ..., decision }] }] } ────── │
```

* Once a dispute is filed, the market transitions from `resolved` to `disputed` and Cournot starts an internal review.
* After the review, the market becomes `closed` and the dispute carries a `decision` — `keep` retains Cournot's verdict, `override` adopts the submitter's selection.
* Partner reads the dispute's progress and final decision via `get_public_market`. Disputes are returned inline as a sub-resource on the market — there is no separate dispute-read endpoint.

## Response envelope

All responses share the same envelope and **always return HTTP 200**. Success vs. failure is signalled by the `code` field, not the HTTP status code.

**Success:**

```json
{ "code": 0, "msg": "Success", "data": { /* endpoint payload */ } }
```

**Error:**

```json
{ "code": 4100, "msg": "slug is required", "detail": "slug is required" }
```

| field    | type   | description                                                |
| -------- | ------ | ---------------------------------------------------------- |
| `code`   | int    | `0` = success; non-zero = error                            |
| `msg`    | string | human-readable message                                     |
| `data`   | object | present on success; carries the endpoint payload           |
| `detail` | string | present on error; additional detail (often equal to `msg`) |

**Integration note:** do not branch on HTTP status. Read `code` — `0` means success and `data` is populated; any other value means the request failed and `msg` / `detail` describe why.

The endpoint specs below describe the contents of `data`.

## 1) get\_public\_market

Look up a market's public record by `slug` + `source`. This is a **market endpoint**: it returns the market's status / verdict / confidence / on-chain proofs, with disputes embedded as a sub-resource on the market. Disputes appear here because they belong to the market — there is no separate dispute-read endpoint.

|            |                           |
| ---------- | ------------------------- |
| **Method** | `GET`                     |
| **Path**   | `/cournot/markets/public` |
| **Auth**   | none (anonymous)          |

**Query params**

| field    | type   | required | description                                  |
| -------- | ------ | -------: | -------------------------------------------- |
| `slug`   | string |      yes | market slug (no leading/trailing `/`)        |
| `source` | string |      yes | Partner-specific source id issued by Cournot |

**`data.markets[]` (`market_item`)**

| field         | type                       | description                                          |
| ------------- | -------------------------- | ---------------------------------------------------- |
| `id`          | int64                      | market id                                            |
| `source`      | string                     | request source                                       |
| `slug`        | string                     | request slug                                         |
| `status`      | string                     | `monitoring` · `resolved` · `disputed` · `closed`    |
| `verdict`     | string                     | final verdict                                        |
| `resolved_at` | string                     | RFC3339 UTC, e.g. `2026-04-28T10:30:00Z`             |
| `confidence`  | string                     | `VERY_HIGH` · `HIGH` · `MEDIUM` · `LOW` · `VERY_LOW` |
| `reasoning`   | string                     | human-readable explanation of the verdict            |
| `proofs`      | `proof_item[]`             | on-chain proofs                                      |
| `disputes`    | `dispute_item[]` \| `null` | dispute list; `null` when the market has no disputes |

**`proof_item`**

| field     | type   | description    |
| --------- | ------ | -------------- |
| `chain`   | string | `base` · `bsc` |
| `tx_hash` | string | tx hash        |

**`dispute_item`**

| field                 | type             | description                               |
| --------------------- | ---------------- | ----------------------------------------- |
| `id`                  | int64            | dispute id                                |
| `status`              | string           | `open` · `closed`                         |
| `submitter_selection` | string           | submitter's claimed outcome               |
| `reason_text`         | string           | dispute reason                            |
| `submitted_at`        | string           | RFC3339 UTC                               |
| `decision`            | object \| `null` | present only when the dispute is `closed` |

**`decision`**

| field                   | type   | description                                                   |
| ----------------------- | ------ | ------------------------------------------------------------- |
| `type`                  | string | `keep` · `override`                                           |
| `partner_final_verdict` | string | `override` → `submitter_selection`; `keep` → market `verdict` |
| `reason_text`           | string | decision reason                                               |
| `decided_at`            | string | RFC3339 UTC                                                   |

**Example**

```bash
curl -G "https://interface.cournot.ai/cournot/markets/public" \
  --data-urlencode "slug=ram-average-price-above-600-by-end-of-march" \
  --data-urlencode "source=YOUR_SOURCE_ID"
```

```json
{
  "code": 0,
  "msg": "Success",
  "data": {
    "markets": [
      {
        "id": 61,
        "source": "YOUR_SOURCE_ID",
        "slug": "ram-average-price-above-600-by-end-of-march",
        "status": "resolved",
        "verdict": "YES",
        "resolved_at": "2026-04-28T10:08:40Z",
        "confidence": "HIGH",
        "reasoning": "multi-source evidence confirmed the final outcome is YES",
        "proofs": [
          { "chain": "base", "tx_hash": "0xabc..." },
          { "chain": "bsc", "tx_hash": "0xdef..." }
        ],
        "disputes": [
          {
            "id": 4,
            "status": "closed",
            "submitter_selection": "NO",
            "reason_text": "we believe the resolved outcome is incorrect based on source evidence",
            "submitted_at": "2026-04-28T10:30:00Z",
            "decision": {
              "type": "override",
              "partner_final_verdict": "NO",
              "reason_text": "submitted dispute is valid",
              "decided_at": "2026-04-28T11:00:00Z"
            }
          }
        ]
      }
    ]
  }
}
```

When the market has no disputes, `disputes` is `null` (not `[]`). When no market matches `slug` + `source`, `data.markets` is `[]`.

## 2) submit\_dispute

File a dispute on behalf of an end user on the Partner platform.

|                  |                                          |
| ---------------- | ---------------------------------------- |
| **Method**       | `POST`                                   |
| **Path**         | `/cournot/markets/dispute/submit`        |
| **Auth**         | header `x-api-key: YOUR_PARTNER_API_KEY` |
| **Content-Type** | `application/json`                       |

**Request body**

| field                 | type   | required | description                                                 |
| --------------------- | ------ | -------: | ----------------------------------------------------------- |
| `market_id`           | int64  |      yes | market id                                                   |
| `submitter_id`        | string |      yes | end user's unique id on the partner side                    |
| `submitter_name`      | string |      yes | submitter display name                                      |
| `submitter_selection` | string |      yes | outcome the submitter claims is correct (e.g. `YES` / `NO`) |
| `reason_text`         | string |      yes | dispute reason                                              |
| `submitted_at`        | string |      yes | RFC3339 UTC; if omitted/invalid, server uses current time   |

**`data` (response payload)**

| field        | type  | description        |
| ------------ | ----- | ------------------ |
| `dispute_id` | int64 | created dispute id |

**Business rules**

* `x-api-key` must be valid.
* The partner's `source` (resolved from the API key) must equal the market's `source` — no cross-partner disputes.
* Only markets with `status = resolved` can be disputed.
* A market can have at most one dispute (a second submission errors out).

**Example**

```bash
curl -X POST "https://interface.cournot.ai/cournot/markets/dispute/submit" \
  -H "content-type: application/json" \
  -H "x-api-key: YOUR_PARTNER_API_KEY" \
  -d '{
    "market_id": 61,
    "submitter_id": "partner_user_1001",
    "submitter_name": "alice",
    "submitter_selection": "NO",
    "reason_text": "we believe the resolved outcome is incorrect based on source evidence",
    "submitted_at": "2026-04-28T10:30:00Z"
  }'
```

```json
{ "code": 0, "msg": "Success", "data": { "dispute_id": 4 } }
```
