{
  "openapi": "3.0.3",
  "info": {
    "title": "NewsCord Article Feed",
    "version": "1.0.0",
    "description": "API-key-protected read-only archive of published NewsCord stories. Full saved source texts and analysis included. Default 3600 requests per key per UTC hour, configurable by operator. Responses are private/no-store. 429 includes Retry-After."
  },
  "servers": [
    {
      "url": "https://newscord.org/api/v1"
    }
  ],
  "paths": {
    "/articles": {
      "get": {
        "operationId": "listArticles",
        "security": [
          {
            "feedKey": []
          }
        ],
        "parameters": [
          {
            "name": "topic",
            "in": "query",
            "description": "Exact case-sensitive topic from /topics",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 120
            }
          },
          {
            "name": "from",
            "in": "query",
            "description": "Inclusive UTC start date on created_at",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "description": "Inclusive UTC end date on created_at",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Stories per page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Opaque continuation; preserve topic and dates",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "pagination"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Article"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "limit": {
                          "type": "integer"
                        },
                        "has_more": {
                          "type": "boolean"
                        },
                        "next_cursor": {
                          "type": "string",
                          "nullable": true
                        },
                        "next_url": {
                          "type": "string",
                          "nullable": true
                        },
                        "snapshot_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/articles/{id}": {
      "get": {
        "operationId": "getArticle",
        "security": [
          {
            "feedKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "URL-encoded collection_id"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Article"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/topics": {
      "get": {
        "operationId": "listTopics",
        "security": [
          {
            "feedKey": []
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "topic": {
                            "type": "string"
                          },
                          "article_count": {
                            "type": "integer",
                            "format": "int64"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Error response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "feedKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Dedicated ncf_ key issued by NewsCord; not an organisation/MCP key"
      }
    },
    "schemas": {
      "Article": {
        "type": "object",
        "additionalProperties": true,
        "description": "Full saved analysis document plus stable convenience fields. Optional analysis fields evolve over time. Source text is in sources[].text.",
        "required": [
          "id",
          "collection_id",
          "url",
          "headline",
          "created_at",
          "topic",
          "text",
          "sources",
          "images",
          "content_available",
          "metadata"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "collection_id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "headline": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "topic": {
            "type": "string",
            "nullable": true
          },
          "text": {
            "type": "string",
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "properties": {
                "text": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "image": {
                  "type": "string"
                }
              }
            }
          },
          "images": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "photo": {
            "description": "The story's lead photo, chosen for the story from openly licensed sources, with its credit and licence. Null when the story has none. Show the credit and licence beside it.",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/StoryPhoto"
              }
            ]
          },
          "content_available": {
            "type": "boolean"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          }
        }
      },
      "StoryPhoto": {
        "type": "object",
        "required": [
          "kind",
          "src",
          "src_small",
          "credit",
          "licence",
          "source_url",
          "provider"
        ],
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "event",
              "place",
              "person",
              "map",
              "theme"
            ]
          },
          "src": {
            "type": "string",
            "format": "uri",
            "description": "The image, 1600px on its long side."
          },
          "src_small": {
            "type": "string",
            "format": "uri",
            "description": "The image, 800px on its long side."
          },
          "width": {
            "type": "integer",
            "nullable": true
          },
          "height": {
            "type": "integer",
            "nullable": true
          },
          "focus": {
            "type": "string",
            "description": "CSS object-position for cropping, e.g. \"50% 40%\"."
          },
          "alt": {
            "type": "string"
          },
          "caption": {
            "type": "string",
            "description": "What the photo shows."
          },
          "place": {
            "type": "string",
            "nullable": true
          },
          "date": {
            "type": "string",
            "format": "date",
            "nullable": true,
            "description": "When the photo was taken."
          },
          "label": {
            "type": "string",
            "nullable": true,
            "enum": [
              "archive",
              "illustration",
              "map",
              null
            ],
            "description": "archive: not a photo of the reported event; illustration: a stock theme photo; map: a map."
          },
          "credit": {
            "type": "string"
          },
          "credit_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "licence": {
            "type": "string",
            "description": "For example CC BY-SA 4.0, Public domain, Unsplash License, Pexels License, ODbL."
          },
          "licence_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "source_url": {
            "type": "string",
            "format": "uri",
            "description": "The photo's file page."
          },
          "provider": {
            "type": "string",
            "enum": [
              "commons",
              "flickr",
              "unsplash",
              "pexels",
              "library",
              "openstreetmap"
            ]
          }
        }
      }
    }
  }
}
