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

# NewsCover API

{% hint style="info" %}
`GET /v1/newscover`  ·  header `X-API-Key: sk_live_...`  ·  call it from your server  ·  roughly 3,000 entities and 10,000 covers
{% endhint %}

## Overview

NewsCover is a service that provides cover images that fit the news. Send a keyword or a headline, and it instantly returns matching covers from the library. FLASH news already ships with covers attached; this API puts the same covers on **your own news**: your AI-rewritten feed, your editorial desk, your text-only sources. The library currently holds roughly **3,000 entities** and **10,000 covers**, organized into the following categories.

<figure><img src="/files/HFYhRviM8FJKl7Wfx67h" alt=""><figcaption></figcaption></figure>

<a href="https://flash.im/newsroom" class="button primary">Browse the library in Newsroom</a>

<table data-search="false"><thead><tr><th>Category</th><th>Examples</th></tr></thead><tbody><tr><td>Crypto</td><td>Bitcoin, Ethereum, Solana</td></tr><tr><td>Corporate &#x26; Brands</td><td>Tesla, Apple, Binance</td></tr><tr><td>Nations</td><td>United States, Japan, South Korea</td></tr><tr><td>Currencies</td><td>Dollar, Yen, Euro</td></tr><tr><td>Commodities</td><td>Gold, Oil, Copper</td></tr><tr><td>People</td><td>Major politicians, CEOs, investors</td></tr><tr><td>Institutions · Indices · Regulation · Concepts</td><td>Fed, SEC, S&#x26;P 500, CPI</td></tr><tr><td>Other</td><td>Other entities frequent in crypto and economic news</td></tr></tbody></table>

It covers **every constituent of the CMC 500, Nasdaq 100, and S\&P 500**, plus most major global brands and the entities that appear most often in crypto and economic news.

### Standardized covers and the grid system

Every cover is produced as a high-quality image normalized by our grid system (person, symbol, wordmark, and object layouts), passes the grid check, and is deployed only after a final human review.

<div><figure><img src="/files/aEZzezNEc4rE1g89LExQ" alt=""><figcaption></figcaption></figure> <figure><img src="/files/9WDCdwOFnuHaBTL2veOp" alt=""><figcaption></figcaption></figure></div>

<div><figure><img src="/files/hn8ckSuBrf4htx12zxvt" alt=""><figcaption></figcaption></figure> <figure><img src="/files/BbAI4ZrUwgVB1r3vBBAg" alt=""><figcaption></figcaption></figure></div>

## Where to use it

| Your UX surface       | How                                                                                                  |
| --------------------- | ---------------------------------------------------------------------------------------------------- |
| News feed thumbnails  | Many source articles ship without an image; `headline=` fills the gap with a correct, licensed cover |
| Editorial desk        | `q=` + `mode=extended`: the editor picks from every cover the entity group holds                     |
| AI-rewriting pipeline | Register as a tool; one call per article, no keyword extraction (see the AI tool section)            |

## Endpoint

**Request**

```
GET https://api.flash.im/v1/newscover?headline={headline text}
GET https://api.flash.im/v1/newscover?q={keyword1,keyword2,...}
X-API-Key: sk_live_...
```

Same key as the rest of the API. **Call it from your server.**

## Choosing a search mode

|                   | `headline=` headline search     | `q=` keyword search                                                    |
| ----------------- | ------------------------------- | ---------------------------------------------------------------------- |
| Input             | The headline, as-is             | Keywords you extracted, comma-separated, up to **4** (5 or more = 400) |
| Entity extraction | NewsCover engine (automatic)    | You (manual)                                                           |
| Matching          | Strict: minimizes false matches | Loose: favors discoverability                                          |
| Your workload     | None: just forward the text     | Core-keyword selection needed                                          |
| Fit               | Automation, AI-rewritten feeds  | Human editing, clear keywords                                          |

{% hint style="info" %}
Rule of thumb: if a machine (or an AI rewriter) produces your feed, use `headline=`. If a person picks the keywords, either works.
{% endhint %}

## Rules

* `headline=` scans the first 250 characters and returns covers for up to 5 entities in the order they appear; the first is usually the primary subject. Send headlines as-is; do not change their casing
* `q=` ignores case, and keywords resolving to the same entity merge into one result. This enables a backup-keyword pattern (`?q=SamBankmanFried,BankmanFried,SBF` returns one result for whichever spelling is registered)
* Minor spelling differences resolve to the same entity: `Polymarket` / `poly market` / `poly-market` / `POLY_MARKET` all match Polymarket; `$BTC` / `btc` match BTC
* Add `mode=extended` to get **all** covers of the matched entity group in `images`, instead of one randomly assigned cover from the several covers registered to that group
* English only. Proper entity names or tickers match (`Bitcoin`, `BTC`, `Fed`); generic phrases do not (`crypto market crash`)

## Response

**Response** (single keyword matched)

```json
{
  "results": [
    { "matched": true,
      "input": "bitcoin",
      "name": "Bitcoin (BTC)",
      "category": "crypto",
      "images": [
        { "url": "https://.../7y9bQA7UG...",
          "width": 1750, "height": 1000, "mimeType": "image/jpeg",
          "imageId": "7y9bQA7UG2t5...", "groupId": "68c028423b0441..." } ] }
  ]
}
```

**Response** (`q=` no match; a miss is HTTP 200, not an error)

```json
{
  "results": [
    { "matched": false,
      "input": "pemex",
      "name": null,
      "category": null,
      "images": [],
      "message": "No matching image found" }
  ]
}
```

* Images are the original **1750x1000** file. `url` is non-expiring but can change if a cover is replaced; `groupId` identifies the entity's cover group (use it to deduplicate across articles)
* **No-match**: `headline=` returns an empty `results` array; `q=` returns `matched: false` items with a `message`. A check that works in both modes: treat the response as a no-match when `results` has zero items with `matched: true`

## Cover composition & fallback

| Result                       | Action                                                                                   |
| ---------------------------- | ---------------------------------------------------------------------------------------- |
| Two or more entities matched | Split-cover the first two (the two-panel style widely used on X), or use the first alone |
| One matched                  | Single-image cover                                                                       |
| No match                     | Use your own fallback image, or publish the story as text-only news without a cover      |

Same-entity keywords are merged server-side, so any two matched results are always two different entities: safe for split covers.

<figure><img src="/files/1zaAC7CA7RXBzJWfldtL" alt=""><figcaption><p>Split cover example, two entities side by side</p></figcaption></figure>

## Usage patterns

**1. Automated feed** (headline mode, one call per article)

```
GET https://api.flash.im/v1/newscover?headline=Bitcoin surges as SEC approves ETF
```

Call once per article in your publishing pipeline and use the first entity's cover as the article image (the first entity is usually the primary subject). On no-match, fall back to your default image or publish the story as text-only. For AI-rewriting pipelines, register this as a tool (next section).

**2. Editorial pick** (keyword mode + extended)

```
GET https://api.flash.im/v1/newscover?q=bitcoin&mode=extended
```

Returns every cover the entity group holds; the editor picks the one that fits the story. This is the API version of browsing the library.

**3. Split cover for a two-entity story**

```
GET https://api.flash.im/v1/newscover?q=SEC,Bitcoin
```

Two matched results are always two different entities (same-entity keywords merge server-side), so render the first two as a two-panel split cover, the style widely used on X.

## Using NewsCover as an AI tool (function calling)

If you re-edit external news with your own AI before publishing, register NewsCover as a tool for that AI. The rewriting model has already identified the article's entities; with `headline=` it simply passes the headline through, so there is no keyword-extraction step at all.

{% stepper %}
{% step %}

### Register the tool

Add the tool definition to your rewriting prompt.

```json
{
  "name": "get_news_cover",
  "description": "Returns news cover images for the entities in a news headline. Pass the article's headline text as-is; the service extracts entities and returns one cover per entity.",
  "parameters": {
    "type": "object",
    "properties": {
      "headline": { "type": "string", "description": "The article headline in English, unchanged." }
    },
    "required": ["headline"]
  }
}
```

{% endstep %}

{% step %}

### The AI calls it once

While rewriting, the model calls the tool once, passing the headline.
{% endstep %}

{% step %}

### Your handler injects the URL

Your tool handler makes the actual API call and injects the returned `url` into the output (e.g. a `coverImage` field).

```js
async function get_news_cover(headline) {
  const res = await fetch(
    'https://api.flash.im/v1/newscover?headline=' + encodeURIComponent(headline),
    { headers: { 'X-API-Key': process.env.FLASH_API_KEY } }
  );
  return await res.json();
}
```

{% endstep %}
{% endstepper %}

{% hint style="info" %}
**Tips:** take the `url` from the tool response in your orchestrator code, not from text the model transcribed (URLs are long hash strings, so model transcription is error-prone); alternatively have the model output only the `imageId` and inject the URL in code. Define in your system prompt what the AI should do on a no-match (e.g. fall back to your default cover). The added cost is one tool call per article.
{% endhint %}

## Errors

200 (including no-match) · 400 (more than 4 keywords) · 401 (missing or invalid key) · 429 (rate limit; retry after `Retry-After`)

## License & credit

{% hint style="warning" %}
Covers are licensed for **editorial use**: identifying the company, asset, or person in news coverage. Within this purpose, publishing, cropping, resizing, and hotlinking are allowed. Use outside news coverage (advertising, merchandise), resale or re-licensing, and redistribution as an image collection are not permitted.

Credit covers as <mark style="color:blue;">**\[Powered by FLASH]**</mark>
{% endhint %}
