{
  "openapi": "3.1.0",
  "info": {
    "title": "StocksNews API",
    "version": "1.0.0",
    "summary": "Curated, ticker-tagged stock news with publisher reputation built in.",
    "description": "About 9,000 vetted headlines a day across 9,700 tickers, scored for relevance. Authenticate with an API key from https://app.stocksnews.app/app/developer. Plans and limits: https://app.stocksnews.app/enterprise/pricing. Articles carry a summary and a link back to the publisher, never the full text.",
    "contact": {
      "email": "support@stocksnews.app",
      "url": "https://app.stocksnews.app/enterprise/contact"
    },
    "termsOfService": "https://app.stocksnews.app/enterprise/pricing#terms"
  },
  "servers": [
    {
      "url": "https://app.stocksnews.app/api/v1"
    }
  ],
  "security": [
    {
      "ApiKeyHeader": []
    },
    {
      "ApiKeyQuery": []
    }
  ],
  "tags": [
    {
      "name": "News"
    },
    {
      "name": "Tickers"
    },
    {
      "name": "Sources"
    },
    {
      "name": "Account"
    }
  ],
  "paths": {
    "/news/{ticker}": {
      "get": {
        "tags": [
          "News"
        ],
        "operationId": "newsByTicker",
        "summary": "Latest news for one ticker",
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "description": "Ticker symbol, e.g. AAPL (case-insensitive).",
            "schema": {
              "type": "string"
            },
            "required": true
          },
          {
            "name": "days",
            "in": "query",
            "description": "Only articles ingested in the last N days. Clamped to the plan's history window.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Articles per page (default 50). Clamped to the plan's max per request.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "`newest` (default) or `relevance`.",
            "schema": {
              "type": "string",
              "enum": [
                "newest",
                "relevance"
              ]
            }
          },
          {
            "name": "before",
            "in": "query",
            "description": "Cursor from `next_cursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "min_score",
            "in": "query",
            "description": "Minimum relevance score.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100
            }
          },
          {
            "name": "importance",
            "in": "query",
            "description": "`critical` to keep only critical items.",
            "schema": {
              "type": "string",
              "enum": [
                "critical"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of articles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "success"
                    },
                    "plan": {
                      "type": "string"
                    },
                    "days": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "sort": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass as `before` to get the next page; null on the last page"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Article"
                      }
                    },
                    "ticker": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit-Minute": {
                "schema": {
                  "type": "string"
                },
                "description": "Requests allowed per minute"
              },
              "X-RateLimit-Remaining-Minute": {
                "schema": {
                  "type": "string"
                },
                "description": "Left this minute"
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "string"
                },
                "description": "Requests allowed per UTC day (or `unlimited`)"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "string"
                },
                "description": "Left today"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "string"
                },
                "description": "Unix time of the next daily reset"
              },
              "X-Api-Plan": {
                "schema": {
                  "type": "string"
                },
                "description": "Plan of the calling key"
              }
            }
          },
          "404": {
            "description": "Ticker not covered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Bad cursor, sort or date",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per minute) or `quota_exceeded` (per day); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/news": {
      "get": {
        "tags": [
          "News"
        ],
        "operationId": "searchNews",
        "summary": "Search across tickers and headlines (Starter and up)",
        "description": "Requires the `search` feature. Defaults to the last 7 days.",
        "parameters": [
          {
            "name": "tickers",
            "in": "query",
            "description": "Comma-separated tickers, at most 20.",
            "schema": {
              "type": "string",
              "example": "AAPL,MSFT"
            }
          },
          {
            "name": "q",
            "in": "query",
            "description": "Text to find in the headline (max 120 chars).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "published_after",
            "in": "query",
            "description": "ISO-8601 lower bound on ingestion time.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "published_before",
            "in": "query",
            "description": "ISO-8601 upper bound.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "days",
            "in": "query",
            "description": "Only articles ingested in the last N days. Clamped to the plan's history window.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Articles per page (default 50). Clamped to the plan's max per request.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "sort",
            "in": "query",
            "description": "`newest` (default) or `relevance`.",
            "schema": {
              "type": "string",
              "enum": [
                "newest",
                "relevance"
              ]
            }
          },
          {
            "name": "before",
            "in": "query",
            "description": "Cursor from `next_cursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "min_score",
            "in": "query",
            "description": "Minimum relevance score.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100
            }
          },
          {
            "name": "importance",
            "in": "query",
            "description": "`critical` to keep only critical items.",
            "schema": {
              "type": "string",
              "enum": [
                "critical"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of articles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "success"
                    },
                    "plan": {
                      "type": "string"
                    },
                    "days": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "sort": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass as `before` to get the next page; null on the last page"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Article"
                      }
                    },
                    "tickers": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "q": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            },
            "headers": {
              "X-RateLimit-Limit-Minute": {
                "schema": {
                  "type": "string"
                },
                "description": "Requests allowed per minute"
              },
              "X-RateLimit-Remaining-Minute": {
                "schema": {
                  "type": "string"
                },
                "description": "Left this minute"
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "string"
                },
                "description": "Requests allowed per UTC day (or `unlimited`)"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "string"
                },
                "description": "Left today"
              },
              "X-RateLimit-Reset": {
                "schema": {
                  "type": "string"
                },
                "description": "Unix time of the next daily reset"
              },
              "X-Api-Plan": {
                "schema": {
                  "type": "string"
                },
                "description": "Plan of the calling key"
              }
            }
          },
          "403": {
            "description": "Feature not in plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "None of the tickers are covered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Bad parameter",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per minute) or `quota_exceeded` (per day); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/articles/{id}": {
      "get": {
        "tags": [
          "News"
        ],
        "operationId": "getArticle",
        "summary": "One article by id",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "Article id",
            "schema": {
              "type": "integer"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "The article",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "success"
                    },
                    "count": {
                      "const": 1
                    },
                    "data": {
                      "$ref": "#/components/schemas/Article"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Older than the plan's history window",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No such article",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per minute) or `quota_exceeded` (per day); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tickers": {
      "get": {
        "tags": [
          "Tickers"
        ],
        "operationId": "listTickers",
        "summary": "Covered tickers",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Prefix of the symbol or part of the company name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sector",
            "in": "query",
            "description": "Exact sector name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Articles per page (default 50). Clamped to the plan's max per request.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "before",
            "in": "query",
            "description": "Cursor from `next_cursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of tickers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "success"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Ticker"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per minute) or `quota_exceeded` (per day); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tickers/{ticker}": {
      "get": {
        "tags": [
          "Tickers"
        ],
        "operationId": "getTicker",
        "summary": "One ticker with coverage counts",
        "parameters": [
          {
            "name": "ticker",
            "in": "path",
            "description": "Ticker symbol",
            "schema": {
              "type": "string"
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "The ticker",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "success"
                    },
                    "data": {
                      "allOf": [
                        {
                          "$ref": "#/components/schemas/Ticker"
                        },
                        {
                          "type": "object",
                          "properties": {
                            "coverage": {
                              "type": "object",
                              "properties": {
                                "headlines_7d": {
                                  "type": "integer"
                                },
                                "headlines_30d": {
                                  "type": "integer"
                                }
                              }
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not covered",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per minute) or `quota_exceeded` (per day); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/sources": {
      "get": {
        "tags": [
          "Sources"
        ],
        "operationId": "listSources",
        "summary": "Publishers with reputation tier and scores (Growth and up)",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "description": "Part of the name or URL.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tier",
            "in": "query",
            "description": "tier_1 \u2026 tier_5",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Articles per page (default 50). Clamped to the plan's max per request.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "before",
            "in": "query",
            "description": "Cursor from `next_cursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of sources",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "success"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Source"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Feature not in plan",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per minute) or `quota_exceeded` (per day); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/usage": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getUsage",
        "summary": "Usage of the calling key, today and the last 30 days",
        "responses": {
          "200": {
            "description": "Usage",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "const": "success"
                    },
                    "key": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "prefix": {
                          "type": "string"
                        },
                        "plan": {
                          "type": "string"
                        }
                      }
                    },
                    "limits": {
                      "type": "object"
                    },
                    "today": {
                      "$ref": "#/components/schemas/UsageDay"
                    },
                    "days": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/UsageDay"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited` (per minute) or `quota_exceeded` (per day); see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      },
      "ApiKeyQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "key"
      }
    },
    "schemas": {
      "Article": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "example": 812331
          },
          "title": {
            "type": "string",
            "example": "Apple beats on iPhone revenue, guides higher"
          },
          "summary": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 301,
            "description": "First 300 characters of the article. The full text is never returned; follow `link`."
          },
          "link": {
            "type": "string",
            "format": "uri"
          },
          "source": {
            "type": "object",
            "properties": {
              "id": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "logo": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "tickers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "AAPL"
            ]
          },
          "score": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0,
            "maximum": 100,
            "description": "Relevance score"
          },
          "importance": {
            "type": "string",
            "enum": [
              "normal",
              "critical"
            ]
          },
          "image": {
            "type": [
              "string",
              "null"
            ]
          },
          "posted_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When StocksNews ingested it (the `days` window uses this)"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "status",
          "code",
          "message"
        ],
        "properties": {
          "status": {
            "const": "error"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Ticker": {
        "type": "object",
        "properties": {
          "ticker": {
            "type": "string"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "sector": {
            "type": [
              "string",
              "null"
            ]
          },
          "subindustry": {
            "type": [
              "string",
              "null"
            ]
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "logo": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Source": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "url": {
            "type": [
              "string",
              "null"
            ]
          },
          "logo": {
            "type": [
              "string",
              "null"
            ]
          },
          "category": {
            "type": [
              "string",
              "null"
            ]
          },
          "tier": {
            "type": [
              "string",
              "null"
            ],
            "description": "tier_1 (wire/major) \u2026 tier_5"
          },
          "reliability": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "high",
              "medium",
              "low",
              null
            ]
          },
          "content_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "scores": {
            "type": "object",
            "properties": {
              "total": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "tranco": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "pagerank": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "wikipedia": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "ai_tier": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "ai_content": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "feed_health": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "headlines_total": {
            "type": "integer"
          },
          "last_seen_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "UsageDay": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "requests": {
            "type": "integer"
          },
          "rejected": {
            "type": "integer"
          },
          "articles": {
            "type": "integer"
          }
        }
      }
    }
  }
}