# Pingle Censorship API

- **OpenAPI Version:** `3.1.0`
- **API Version:** `0.1.0`

The Pingle Censorship API provides public, read-only access to country-level censorship risk, incident records, evidence links, source metadata, and AI service accessibility signals.

Use it to power monitoring dashboards, research pipelines, editorial workflows, civic transparency projects, and connectivity-aware products that need a stable machine-readable view of internet censorship conditions. Public operations are GET-only, require no API key, and are served from `https://api.pingle.one`.

## Quickstart

```bash
curl https://api.pingle.one/v1/countries
```

## Methodology

Scores are deterministic and combine measurements, incident severity, source corroboration, recency, and confidence. AI-assisted analysis can support private classification and review workflows, but AI output does not assign country scores or turn provider-side restrictions into censorship scores by itself.

## Data model

Country scores summarize current censorship pressure. Incidents describe observed blocking or interference events, evidence links connect incidents to public measurements or source material, and sources explain provenance and freshness.

## Safety boundary

Mutating ingestion, review, moderation, and administration workflows are private systems and are not exposed in this public contract. The API is intended for retrieval, analysis, citation, and synchronization; clients should treat unknown or missing measurements as insufficient data rather than censorship evidence.

## Servers

- **URL:** `https://api.pingle.one`

## Operations

### Accessibility Check

- **Method:** `GET`
- **Path:** `/v1/accessibility/check`
- **Tags:** AI Accessibility

Use this endpoint to look up the current accessibility signal for a specific domain and country pair. It returns an existing measurement when available and otherwise reports insufficient data without creating a new probe.

#### Parameters

##### `domain` required

- **In:** `query`

`string`

##### `country` required

- **In:** `query`

`string`

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

- **`country_code` (required)**

  `string`

- **`degraded` (required)**

  `boolean`

- **`domain` (required)**

  `string`

- **`evidence_ids` (required)**

  `array`

  **Items:**

  `string`

- **`inflates_censorship_score` (required)**

  `boolean`

- **`network_blocked` (required)**

  `boolean`

- **`provider_restricted` (required)**

  `boolean`

- **`service_id` (required)**

  `string`

- **`status` (required)**

  `string`, possible values: `"accessible", "blocked", "degraded", "provider_restricted", "insufficient_data", "unknown"`

**Example:**

```json
{
  "country_code": "",
  "degraded": true,
  "domain": "",
  "evidence_ids": [
    ""
  ],
  "inflates_censorship_score": true,
  "network_blocked": true,
  "provider_restricted": true,
  "service_id": "",
  "status": "accessible"
}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

##### Status: 404 Not found

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### AI Service Catalog

- **Method:** `GET`
- **Path:** `/v1/ai-services`
- **Tags:** AI Accessibility

Use this endpoint to discover AI services tracked for accessibility analysis. It provides stable service IDs and metadata that can be used before requesting per-country accessibility status.

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

**Array of:**

- **`domains` (required)**

  `array`

  **Items:**

  `string`

- **`name` (required)**

  `string`

- **`service_id` (required)**

  `string`

**Example:**

```json
[
  {
    "domains": [
      ""
    ],
    "name": "",
    "service_id": ""
  }
]
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

##### Status: 404 Not found

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### AI Service Country Matrix

- **Method:** `GET`
- **Path:** `/v1/ai-services/{service_id}/countries`
- **Tags:** AI Accessibility

Use this endpoint to list country-level accessibility results for a tracked AI service. It is useful for products that show where a provider is blocked, degraded, restricted by provider policy, or not yet sufficiently measured.

#### Parameters

##### `service_id` required

- **In:** `path`

`string`

##### `cursor`

- **In:** `query`

`string`

##### `limit`

- **In:** `query`

`integer`

##### `from`

- **In:** `query`

`string`, format: `date-time`

##### `to`

- **In:** `query`

`string`, format: `date-time`

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

- **`data` (required)**

  `array`

  **Items:**

  - **`country_code` (required)**

    `string`

  - **`degraded` (required)**

    `boolean`

  - **`domain` (required)**

    `string`

  - **`evidence_ids` (required)**

    `array`

    **Items:**

    `string`

  - **`inflates_censorship_score` (required)**

    `boolean`

  - **`network_blocked` (required)**

    `boolean`

  - **`provider_restricted` (required)**

    `boolean`

  - **`service_id` (required)**

    `string`

  - **`status` (required)**

    `string`, possible values: `"accessible", "blocked", "degraded", "provider_restricted", "insufficient_data", "unknown"`

- **`next_cursor` (required)**

  `string | null`

**Example:**

```json
{
  "data": [
    {
      "country_code": "",
      "degraded": true,
      "domain": "",
      "evidence_ids": [
        ""
      ],
      "inflates_censorship_score": true,
      "network_blocked": true,
      "provider_restricted": true,
      "service_id": "",
      "status": null
    }
  ],
  "next_cursor": null
}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Countries

- **Method:** `GET`
- **Path:** `/v1/countries`
- **Tags:** Country Intelligence

Use this endpoint to discover the countries currently covered by the API. It is the stable lookup table for country codes used by score, profile, incident, and accessibility endpoints.

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

**Array of:**

- **`country_code` (required)**

  `string`

- **`country_name` (required)**

  `string`

**Example:**

```json
[
  {
    "country_code": "",
    "country_name": ""
  }
]
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

##### Status: 404 Not found

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Country

- **Method:** `GET`
- **Path:** `/v1/countries/{country_code}`
- **Tags:** Country Intelligence

Use this endpoint to resolve an ISO 3166-1 alpha-2 code to the country record used by Pingle. It is useful when validating user input or displaying country names before requesting score or profile data.

#### Parameters

##### `country_code` required

- **In:** `path`

`string`

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

- **`country_code` (required)**

  `string`

- **`country_name` (required)**

  `string`

**Example:**

```json
{
  "country_code": "",
  "country_name": ""
}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

##### Status: 404 Not found

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Country Incidents

- **Method:** `GET`
- **Path:** `/v1/countries/{country_code}/incidents`
- **Tags:** Incident Intelligence

Use this endpoint to list incidents observed for one country, with pagination and optional time filters. It is the right source for country-specific timelines, alerts, and investigation queues.

#### Parameters

##### `country_code` required

- **In:** `path`

`string`

##### `cursor`

- **In:** `query`

`string`

##### `limit`

- **In:** `query`

`integer`

##### `from`

- **In:** `query`

`string`, format: `date-time`

##### `to`

- **In:** `query`

`string`, format: `date-time`

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

- **`data` (required)**

  `array`

  **Items:**

  - **`canonical_url` (required)**

    `string`

  - **`country_code` (required)**

    `string`

  - **`incident_id` (required)**

    `string`

  - **`incident_type` (required)**

    `string`

  - **`severity` (required)**

    `string`

  - **`started_at` (required)**

    `string`, format: `date-time`

  - **`status` (required)**

    `string`

  - **`summary` (required)**

    `string`

  - **`title` (required)**

    `string`

  - **`updated_at` (required)**

    `string`, format: `date-time`

  - **`ended_at`**

    `string | null`, format: `date-time`

- **`next_cursor` (required)**

  `string | null`

**Example:**

```json
{
  "data": [
    {
      "canonical_url": "",
      "country_code": "",
      "ended_at": null,
      "incident_id": "",
      "incident_type": "",
      "severity": "",
      "started_at": "",
      "status": "",
      "summary": "",
      "title": "",
      "updated_at": ""
    }
  ],
  "next_cursor": null
}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Country Profile

- **Method:** `GET`
- **Path:** `/v1/countries/{country_code}/profile`
- **Tags:** Country Intelligence

Use this endpoint when a product needs one consolidated country view. It combines country metadata, the latest score, recent incidents, and public source metadata for country detail pages or risk panels.

#### Parameters

##### `country_code` required

- **In:** `path`

`string`

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

- **`country` (required)**

  `object`

  - **`country_code` (required)**

    `string`

  - **`country_name` (required)**

    `string`

- **`recent_incidents` (required)**

  `array`

  **Items:**

  - **`canonical_url` (required)**

    `string`

  - **`country_code` (required)**

    `string`

  - **`incident_id` (required)**

    `string`

  - **`incident_type` (required)**

    `string`

  - **`severity` (required)**

    `string`

  - **`started_at` (required)**

    `string`, format: `date-time`

  - **`status` (required)**

    `string`

  - **`summary` (required)**

    `string`

  - **`title` (required)**

    `string`

  - **`updated_at` (required)**

    `string`, format: `date-time`

  - **`ended_at`**

    `string | null`, format: `date-time`

- **`sources` (required)**

  `array`

  **Items:**

  - **`adapter_strategy` (required)**

    `string`, possible values: `"measurement_backed", "feed_backed", "transparency_backed", "provider_status_backed", "discovery_only"`

  - **`category` (required)**

    `string`, possible values: `"primary_measurement", "civil_society_research_news", "transparency_report", "discovery_evidence_capture", "provider_status_transparency"`

  - **`config_metadata_json` (required)**

    `string`

  - **`freshness_hours` (required)**

    `integer`, format: `uint16`

  - **`homepage_url` (required)**

    `string`

  - **`is_public` (required)**

    `boolean`

  - **`kind` (required)**

    `string`, possible values: `"measurement_api", "measurement_dataset", "measurement_report", "rss_feed", "research_report", "transparency_report", "provider_status_page", "discovery_adapter", "evidence_capture_adapter", "site_query"`

  - **`name` (required)**

    `string`

  - **`source_id` (required)**

    `string`

  - **`source_of_truth` (required)**

    `boolean`

  - **`tier` (required)**

    `string`, possible values: `"primary", "trusted", "corroborating", "discovery_only"`

  - **`docs_url`**

    `string | null`

  - **`feed_url`**

    `string | null`

- **`latest_score`**

  `object`

**Example:**

```json
{
  "country": {
    "country_code": "",
    "country_name": ""
  },
  "latest_score": {
    "bucket": "",
    "calculated_at": "",
    "confidence": 1,
    "country_code": "",
    "country_name": "",
    "drivers": [],
    "methodology_version": "",
    "score": 1,
    "trend": ""
  },
  "recent_incidents": [
    {
      "canonical_url": "",
      "country_code": "",
      "ended_at": null,
      "incident_id": "",
      "incident_type": "",
      "severity": "",
      "started_at": "",
      "status": "",
      "summary": "",
      "title": "",
      "updated_at": ""
    }
  ],
  "sources": [
    {
      "adapter_strategy": null,
      "category": null,
      "config_metadata_json": "",
      "docs_url": null,
      "feed_url": null,
      "freshness_hours": 0,
      "homepage_url": "",
      "is_public": true,
      "kind": null,
      "name": "",
      "source_id": "",
      "source_of_truth": true,
      "tier": null
    }
  ]
}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

##### Status: 404 Not found

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Incident JSONL Export

- **Method:** `GET`
- **Path:** `/v1/exports/incidents.jsonl`
- **Tags:** Data Sync

Use this endpoint to download incidents as newline-delimited JSON for analytics, archival, or ETL pipelines. It supports the same incident filters as list endpoints while returning a stream-friendly text format.

#### Responses

##### Status: 200 Success

###### Content-Type: application/x-ndjson

`string`

**Example:**

```json
""
```

### Incidents

- **Method:** `GET`
- **Path:** `/v1/incidents`
- **Tags:** Incident Intelligence

Use this endpoint to search the incident catalog across countries. Filters let integrations build global monitoring views by country, severity, status, source, incident type, and time window.

#### Parameters

##### `cursor`

- **In:** `query`

`string`

##### `limit`

- **In:** `query`

`integer`

##### `from`

- **In:** `query`

`string`, format: `date-time`

##### `to`

- **In:** `query`

`string`, format: `date-time`

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

- **`data` (required)**

  `array`

  **Items:**

  - **`canonical_url` (required)**

    `string`

  - **`country_code` (required)**

    `string`

  - **`incident_id` (required)**

    `string`

  - **`incident_type` (required)**

    `string`

  - **`severity` (required)**

    `string`

  - **`started_at` (required)**

    `string`, format: `date-time`

  - **`status` (required)**

    `string`

  - **`summary` (required)**

    `string`

  - **`title` (required)**

    `string`

  - **`updated_at` (required)**

    `string`, format: `date-time`

  - **`ended_at`**

    `string | null`, format: `date-time`

- **`next_cursor` (required)**

  `string | null`

**Example:**

```json
{
  "data": [
    {
      "canonical_url": "",
      "country_code": "",
      "ended_at": null,
      "incident_id": "",
      "incident_type": "",
      "severity": "",
      "started_at": "",
      "status": "",
      "summary": "",
      "title": "",
      "updated_at": ""
    }
  ],
  "next_cursor": null
}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Incident Delta

- **Method:** `GET`
- **Path:** `/v1/incidents/delta`
- **Tags:** Data Sync

Use this endpoint to synchronize incident changes since a timestamp. It is designed for scheduled jobs that need incremental updates without repeatedly fetching the full incident catalog.

#### Parameters

##### `since` required

- **In:** `query`

`string`, format: `date-time`

##### `cursor`

- **In:** `query`

`string`

##### `limit`

- **In:** `query`

`integer`

##### `country`

- **In:** `query`

`string`

##### `severity`

- **In:** `query`

`string`

##### `status`

- **In:** `query`

`string`

##### `source`

- **In:** `query`

`string`

##### `incident_type`

- **In:** `query`

`string`

##### `to`

- **In:** `query`

`string`, format: `date-time`

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

- **`data` (required)**

  `array`

  **Items:**

  - **`canonical_url` (required)**

    `string`

  - **`country_code` (required)**

    `string`

  - **`incident_id` (required)**

    `string`

  - **`incident_type` (required)**

    `string`

  - **`severity` (required)**

    `string`

  - **`started_at` (required)**

    `string`, format: `date-time`

  - **`status` (required)**

    `string`

  - **`summary` (required)**

    `string`

  - **`title` (required)**

    `string`

  - **`updated_at` (required)**

    `string`, format: `date-time`

  - **`ended_at`**

    `string | null`, format: `date-time`

- **`next_cursor` (required)**

  `string | null`

**Example:**

```json
{
  "data": [
    {
      "canonical_url": "",
      "country_code": "",
      "ended_at": null,
      "incident_id": "",
      "incident_type": "",
      "severity": "",
      "started_at": "",
      "status": "",
      "summary": "",
      "title": "",
      "updated_at": ""
    }
  ],
  "next_cursor": null
}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Incident

- **Method:** `GET`
- **Path:** `/v1/incidents/{incident_id}`
- **Tags:** Incident Intelligence

Use this endpoint to retrieve the canonical record for a single incident. It gives clients a stable detail page payload and a durable ID for linking evidence, reports, and exports.

#### Parameters

##### `incident_id` required

- **In:** `path`

`string`

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

- **`canonical_url` (required)**

  `string`

- **`country_code` (required)**

  `string`

- **`incident_id` (required)**

  `string`

- **`incident_type` (required)**

  `string`

- **`severity` (required)**

  `string`

- **`started_at` (required)**

  `string`, format: `date-time`

- **`status` (required)**

  `string`

- **`summary` (required)**

  `string`

- **`title` (required)**

  `string`

- **`updated_at` (required)**

  `string`, format: `date-time`

- **`ended_at`**

  `string | null`, format: `date-time`

**Example:**

```json
{
  "canonical_url": "",
  "country_code": "",
  "ended_at": null,
  "incident_id": "",
  "incident_type": "",
  "severity": "",
  "started_at": "",
  "status": "",
  "summary": "",
  "title": "",
  "updated_at": ""
}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

##### Status: 404 Not found

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Incident Evidence

- **Method:** `GET`
- **Path:** `/v1/incidents/{incident_id}/evidence`
- **Tags:** Incident Intelligence

Use this endpoint to list public evidence attached to an incident. It is intended for researchers and editorial teams that need measurement links, source references, and confidence values behind a claim.

#### Parameters

##### `incident_id` required

- **In:** `path`

`string`

##### `cursor`

- **In:** `query`

`string`

##### `limit`

- **In:** `query`

`integer`

##### `from`

- **In:** `query`

`string`, format: `date-time`

##### `to`

- **In:** `query`

`string`, format: `date-time`

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

- **`data` (required)**

  `array`

  **Items:**

  - **`captured_at` (required)**

    `string`, format: `date-time`

  - **`confidence` (required)**

    `number`, format: `double`

  - **`evidence_id` (required)**

    `string`

  - **`incident_id` (required)**

    `string`

  - **`source_id` (required)**

    `string`

  - **`title` (required)**

    `string`

  - **`url` (required)**

    `string`

- **`next_cursor` (required)**

  `string | null`

**Example:**

```json
{
  "data": [
    {
      "captured_at": "",
      "confidence": 1,
      "evidence_id": "",
      "incident_id": "",
      "source_id": "",
      "title": "",
      "url": ""
    }
  ],
  "next_cursor": null
}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Incident Citation Report

- **Method:** `GET`
- **Path:** `/v1/incidents/{incident_id}/report`
- **Tags:** Incident Intelligence

Use this endpoint to produce a compact citation report for one incident. Markdown is the default for human review, while BibTeX and RIS are available for research tools through the `format` query parameter.

#### Parameters

##### `incident_id` required

- **In:** `path`

`string`

##### `format`

- **In:** `query`

`string`

#### Responses

##### Status: 200 Success

###### Content-Type: text/markdown

`string`

**Example:**

```json
""
```

### Latest Country Index

- **Method:** `GET`
- **Path:** `/v1/index/latest`
- **Tags:** Country Intelligence

Use this endpoint to compare current censorship pressure across all supported countries. It returns the latest deterministic score, confidence, trend, and driver breakdown for each country so dashboards can sort or alert without recalculating the index.

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

**Array of:**

- **`bucket` (required)**

  `string`

- **`calculated_at` (required)**

  `string`, format: `date-time`

- **`confidence` (required)**

  `number`, format: `double`

- **`country_code` (required)**

  `string`

- **`country_name` (required)**

  `string`

- **`drivers` (required)**

  `array`

  **Items:**

  - **`code` (required)**

    `string`

  - **`contribution` (required)**

    `number`, format: `double`

  - **`label` (required)**

    `string`

- **`methodology_version` (required)**

  `string`

- **`score` (required)**

  `number`, format: `double`

- **`trend` (required)**

  `string`

**Example:**

```json
[
  {
    "bucket": "",
    "calculated_at": "",
    "confidence": 1,
    "country_code": "",
    "country_name": "",
    "drivers": [],
    "methodology_version": "",
    "score": 1,
    "trend": ""
  }
]
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

##### Status: 404 Not found

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### AI Platform Risk

- **Method:** `GET`
- **Path:** `/v1/platforms/ai/risk`
- **Tags:** AI Accessibility

Use this endpoint to read the current scoring policy for provider-side AI restrictions. It clarifies whether provider restrictions inflate censorship scores so clients do not overstate censorship risk.

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

**Example:**

```json
{}
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

##### Status: 404 Not found

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Sources

- **Method:** `GET`
- **Path:** `/v1/sources`
- **Tags:** Incident Intelligence

Use this endpoint to inspect the public source catalog used by the index. It helps integrators explain provenance, filter records by source family, and display freshness or source-of-truth metadata.

#### Responses

##### Status: 200 Success

###### Content-Type: application/json

**Array of:**

- **`adapter_strategy` (required)**

  `string`, possible values: `"measurement_backed", "feed_backed", "transparency_backed", "provider_status_backed", "discovery_only"`

- **`category` (required)**

  `string`, possible values: `"primary_measurement", "civil_society_research_news", "transparency_report", "discovery_evidence_capture", "provider_status_transparency"`

- **`config_metadata_json` (required)**

  `string`

- **`freshness_hours` (required)**

  `integer`, format: `uint16`

- **`homepage_url` (required)**

  `string`

- **`is_public` (required)**

  `boolean`

- **`kind` (required)**

  `string`, possible values: `"measurement_api", "measurement_dataset", "measurement_report", "rss_feed", "research_report", "transparency_report", "provider_status_page", "discovery_adapter", "evidence_capture_adapter", "site_query"`

- **`name` (required)**

  `string`

- **`source_id` (required)**

  `string`

- **`source_of_truth` (required)**

  `boolean`

- **`tier` (required)**

  `string`, possible values: `"primary", "trusted", "corroborating", "discovery_only"`

- **`docs_url`**

  `string | null`

- **`feed_url`**

  `string | null`

**Example:**

```json
[
  {
    "adapter_strategy": null,
    "category": null,
    "config_metadata_json": "",
    "docs_url": null,
    "feed_url": null,
    "freshness_hours": 0,
    "homepage_url": "",
    "is_public": true,
    "kind": null,
    "name": "",
    "source_id": "",
    "source_of_truth": true,
    "tier": null
  }
]
```

##### Status: 400 Validation error

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

##### Status: 404 Not found

###### Content-Type: application/json

- **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

## Schemas

### AccessibilityResult

- **Type:**`object`

* **`country_code` (required)**

  `string`

* **`degraded` (required)**

  `boolean`

* **`domain` (required)**

  `string`

* **`evidence_ids` (required)**

  `array`

  **Items:**

  `string`

* **`inflates_censorship_score` (required)**

  `boolean`

* **`network_blocked` (required)**

  `boolean`

* **`provider_restricted` (required)**

  `boolean`

* **`service_id` (required)**

  `string`

* **`status` (required)**

  `string`, possible values: `"accessible", "blocked", "degraded", "provider_restricted", "insufficient_data", "unknown"`

**Example:**

```json
{
  "country_code": "",
  "degraded": true,
  "domain": "",
  "evidence_ids": [
    ""
  ],
  "inflates_censorship_score": true,
  "network_blocked": true,
  "provider_restricted": true,
  "service_id": "",
  "status": "accessible"
}
```

### AiService

- **Type:**`object`

* **`domains` (required)**

  `array`

  **Items:**

  `string`

* **`name` (required)**

  `string`

* **`service_id` (required)**

  `string`

**Example:**

```json
{
  "domains": [
    ""
  ],
  "name": "",
  "service_id": ""
}
```

### ApiErrorEnvelope

- **Type:**`object`

* **`error` (required)**

  `object`

  - **`code` (required)**

    `string`

  - **`message` (required)**

    `string`

  - **`request_id` (required)**

    `string`

**Example:**

```json
{
  "error": {
    "code": "",
    "message": "",
    "request_id": ""
  }
}
```

### Country

- **Type:**`object`

* **`country_code` (required)**

  `string`

* **`country_name` (required)**

  `string`

**Example:**

```json
{
  "country_code": "",
  "country_name": ""
}
```

### CountryProfile

- **Type:**`object`

* **`country` (required)**

  `object`

  - **`country_code` (required)**

    `string`

  - **`country_name` (required)**

    `string`

* **`recent_incidents` (required)**

  `array`

  **Items:**

  - **`canonical_url` (required)**

    `string`

  - **`country_code` (required)**

    `string`

  - **`incident_id` (required)**

    `string`

  - **`incident_type` (required)**

    `string`

  - **`severity` (required)**

    `string`

  - **`started_at` (required)**

    `string`, format: `date-time`

  - **`status` (required)**

    `string`

  - **`summary` (required)**

    `string`

  - **`title` (required)**

    `string`

  - **`updated_at` (required)**

    `string`, format: `date-time`

  - **`ended_at`**

    `string | null`, format: `date-time`

* **`sources` (required)**

  `array`

  **Items:**

  - **`adapter_strategy` (required)**

    `string`, possible values: `"measurement_backed", "feed_backed", "transparency_backed", "provider_status_backed", "discovery_only"`

  - **`category` (required)**

    `string`, possible values: `"primary_measurement", "civil_society_research_news", "transparency_report", "discovery_evidence_capture", "provider_status_transparency"`

  - **`config_metadata_json` (required)**

    `string`

  - **`freshness_hours` (required)**

    `integer`, format: `uint16`

  - **`homepage_url` (required)**

    `string`

  - **`is_public` (required)**

    `boolean`

  - **`kind` (required)**

    `string`, possible values: `"measurement_api", "measurement_dataset", "measurement_report", "rss_feed", "research_report", "transparency_report", "provider_status_page", "discovery_adapter", "evidence_capture_adapter", "site_query"`

  - **`name` (required)**

    `string`

  - **`source_id` (required)**

    `string`

  - **`source_of_truth` (required)**

    `boolean`

  - **`tier` (required)**

    `string`, possible values: `"primary", "trusted", "corroborating", "discovery_only"`

  - **`docs_url`**

    `string | null`

  - **`feed_url`**

    `string | null`

* **`latest_score`**

  `object`

**Example:**

```json
{
  "country": {
    "country_code": "",
    "country_name": ""
  },
  "latest_score": {
    "bucket": "",
    "calculated_at": "",
    "confidence": 1,
    "country_code": "",
    "country_name": "",
    "drivers": [],
    "methodology_version": "",
    "score": 1,
    "trend": ""
  },
  "recent_incidents": [
    {
      "canonical_url": "",
      "country_code": "",
      "ended_at": null,
      "incident_id": "",
      "incident_type": "",
      "severity": "",
      "started_at": "",
      "status": "",
      "summary": "",
      "title": "",
      "updated_at": ""
    }
  ],
  "sources": [
    {
      "adapter_strategy": null,
      "category": null,
      "config_metadata_json": "",
      "docs_url": null,
      "feed_url": null,
      "freshness_hours": 0,
      "homepage_url": "",
      "is_public": true,
      "kind": null,
      "name": "",
      "source_id": "",
      "source_of_truth": true,
      "tier": null
    }
  ]
}
```

### CountryScore

- **Type:**`object`

* **`bucket` (required)**

  `string`

* **`calculated_at` (required)**

  `string`, format: `date-time`

* **`confidence` (required)**

  `number`, format: `double`

* **`country_code` (required)**

  `string`

* **`country_name` (required)**

  `string`

* **`drivers` (required)**

  `array`

  **Items:**

  - **`code` (required)**

    `string`

  - **`contribution` (required)**

    `number`, format: `double`

  - **`label` (required)**

    `string`

* **`methodology_version` (required)**

  `string`

* **`score` (required)**

  `number`, format: `double`

* **`trend` (required)**

  `string`

**Example:**

```json
{
  "bucket": "",
  "calculated_at": "",
  "confidence": 1,
  "country_code": "",
  "country_name": "",
  "drivers": [
    {
      "code": "",
      "contribution": 1,
      "label": ""
    }
  ],
  "methodology_version": "",
  "score": 1,
  "trend": ""
}
```

### Evidence

- **Type:**`object`

* **`captured_at` (required)**

  `string`, format: `date-time`

* **`confidence` (required)**

  `number`, format: `double`

* **`evidence_id` (required)**

  `string`

* **`incident_id` (required)**

  `string`

* **`source_id` (required)**

  `string`

* **`title` (required)**

  `string`

* **`url` (required)**

  `string`

**Example:**

```json
{
  "captured_at": "",
  "confidence": 1,
  "evidence_id": "",
  "incident_id": "",
  "source_id": "",
  "title": "",
  "url": ""
}
```

### Incident

- **Type:**`object`

* **`canonical_url` (required)**

  `string`

* **`country_code` (required)**

  `string`

* **`incident_id` (required)**

  `string`

* **`incident_type` (required)**

  `string`

* **`severity` (required)**

  `string`

* **`started_at` (required)**

  `string`, format: `date-time`

* **`status` (required)**

  `string`

* **`summary` (required)**

  `string`

* **`title` (required)**

  `string`

* **`updated_at` (required)**

  `string`, format: `date-time`

* **`ended_at`**

  `string | null`, format: `date-time`

**Example:**

```json
{
  "canonical_url": "",
  "country_code": "",
  "ended_at": null,
  "incident_id": "",
  "incident_type": "",
  "severity": "",
  "started_at": "",
  "status": "",
  "summary": "",
  "title": "",
  "updated_at": ""
}
```

### Source

- **Type:**`object`

* **`adapter_strategy` (required)**

  `string`, possible values: `"measurement_backed", "feed_backed", "transparency_backed", "provider_status_backed", "discovery_only"`

* **`category` (required)**

  `string`, possible values: `"primary_measurement", "civil_society_research_news", "transparency_report", "discovery_evidence_capture", "provider_status_transparency"`

* **`config_metadata_json` (required)**

  `string`

* **`freshness_hours` (required)**

  `integer`, format: `uint16`

* **`homepage_url` (required)**

  `string`

* **`is_public` (required)**

  `boolean`

* **`kind` (required)**

  `string`, possible values: `"measurement_api", "measurement_dataset", "measurement_report", "rss_feed", "research_report", "transparency_report", "provider_status_page", "discovery_adapter", "evidence_capture_adapter", "site_query"`

* **`name` (required)**

  `string`

* **`source_id` (required)**

  `string`

* **`source_of_truth` (required)**

  `boolean`

* **`tier` (required)**

  `string`, possible values: `"primary", "trusted", "corroborating", "discovery_only"`

* **`docs_url`**

  `string | null`

* **`feed_url`**

  `string | null`

**Example:**

```json
{
  "adapter_strategy": "measurement_backed",
  "category": "primary_measurement",
  "config_metadata_json": "",
  "docs_url": null,
  "feed_url": null,
  "freshness_hours": 0,
  "homepage_url": "",
  "is_public": true,
  "kind": "measurement_api",
  "name": "",
  "source_id": "",
  "source_of_truth": true,
  "tier": "primary"
}
```
