---
title: "Company description"
description: "POST /v1/company/description — domain in, one stampable English company description out (or null)."
canonical: "https://kingminos.com/docs/api/company-description/"
sourceKind: "source-mdx"
---

import TryItLink from '../../../../components/docs/TryItLink.astro';

`POST https://api.kingminos.com/v1/company/description`

<TryItLink method="POST" path="/v1/company/description" />

Send a company subject: `domain`, `website`, or `email` (hygiene-normalized to the same registrable domain). Optional `name` is a hint for composed text; it is not returned. Name-only input (no domain, website, or email) is `400` `name_only_unsupported`.

```bash
curl 'https://api.kingminos.com/v1/company/description' \
  -H 'Authorization: Bearer <your-key>' \
  -H 'Content-Type: application/json' \
  -d '{
    "domain": "outboundsync.com",
    "name": "OutboundSync",
    "path": "balance",
    "external_ref": "account-demo-1"
  }'
```

## What comes back

The envelope is schema version `2`. Automations branch on these layers:

| Layer | Fields | Use |
| --- | --- | --- |
| Control | `es_decision`, `answer.confidence` | Whether to stamp. |
| Explain | `answer.summary`, `answer.confidence`, `answer.identity`, `sources` | Humans and logs. |
| Quality | `result.flags` | Quality flags on the returned text (see below). |
| Billing | `usage.credits`, `usage.hops` | What ran and what was billed. |
| Audit | `trace` when `X-Router-Explain: full` | Debug only. |

`answer.outcome` on this capability is `hit` or `no_decision`. `es_decision` is `hit`, `miss`, `ambiguous`, `error`, `noop`, or `reject`.

`result.description` is the write field: an English, JSON-safe company description (`max_chars` 80–500, default 300), or `null` on a miss. There is no `company_name` in the result.

`answer.confidence` is `high`, `medium`, or `low` (`null` on a miss). `answer.identity` is `{ "method": "jev" | "name_domain" | "own_homepage", "score": number | null }`: how the text passed the identity check. It is `null` when the hit was not identity-judged.

**Stamp rule:** write `result.description` when `answer.confidence` meets your acceptance floor (path defaults: `speed` / `coverage` allow `low`; `balance` requires `medium`+; `accuracy` requires `high`; override with `min_confidence`). On a billed hit, text must be non-blank and pass the identity gate (`answer.identity` non-null: Jev identity ≥ 0.85, a deterministic name/domain match, or the input domain's own homepage). Below-floor answers return `description: null`; candidates stay in evidence. Even `low` is usable and close to production-grade. See [`GET /v1/recipes/guidance`](https://api.kingminos.com/v1/recipes/guidance).

### Flags

`result.flags` is an object of booleans on a hit (`null` on a miss). Flags are quality signals, not misses. The hit still returns. The object may gain new keys over time; clients should ignore unknown keys.

| Flag | Meaning |
| --- | --- |
| `hype` | Jev hype &gt; 0.7 or leftover superlatives. |
| `first_person` | Any `We` / `Our` / `I` sentence. |
| `tagline` | Slogan, all-caps headline, blog headline, or article summary. |
| `same_as_speed` | A ranked fallback that matches the `speed` winner. |
| `truncated` | Stamp trimmed to the last whole word. Forces confidence `low`. |
| `cta` | Marketing or imperative line (Join N+, trusted-by, exclamation, Get started). Forces confidence `low`. |
| `grammar` | Informational only; does not affect confidence. |

Other result fields: `source_kind` (`quoted` \| `composed`), `language_note` (`filtered` \| `translated` \| `interpreted` \| null), `company_domain`, `compose_echo`, `homepage_meta_only`.

Business misses stay HTTP `200`.

## Routing

Omitting `path` (or `routing.path`) runs the `balance` ladder with a run credit cap of **6**. Set `path` to `balance` explicitly when you want that ladder with cap **2**. The four paths are distinct, nested ladders, not aliases. A more expensive path never misses where a cheaper path hit.

| `path` | What it does | Credit cap |
| --- | --- | --- |
| `speed` | Homepage meta / Open Graph description with deterministic gates, then house **AI Ark**. Lowest spend. | 1 |
| `balance` | When `path` is omitted, this ladder runs and the cap is **6**. With an explicit `balance`, cap **2**. Homepage extracts + meta/og + AI Ark, ranked with **Jev**; optional light neutral rewrite (0.5). May fall back to `speed`'s text with `same_as_speed`. | 2 explicit · 6 if `path` omitted |
| `accuracy` | Neutral third-person **xAI** compose from homepage evidence with one Jev identity check (compose 2). Falls back to the cheaper hit. | 3 |
| `coverage` | Accuracy compose plus off-homepage evidence (house websearch, 0.1) and **ZoomInfo** BYOK when you store a key. Falls back to the accuracy winner, so it cannot miss where accuracy hit. | 6 |

Legacy aliases (`fast`, `value`, `name_only` → `speed`; `auto` → `balance`) expand to the paths above.

**AI Ark** is the only firmographic vendor. LeadMagic, Findymail, Wiza, Brandfetch, Lemlist, and Snov.io are **not** used for `company.description`. **ZoomInfo** is BYOK only (never the house key). See [Vendor keys](/docs/api/credentials/).

## Hard rejects

These never become a hit:

- **Wrong company**: Jev identity below 0.85, or vendor domain/website not matching the subject.
- **Junk or PII**: emails, phones, navigation/cookie/footer text, URLs, mid-word cuts, nameless fragments.
- **Empty**: no usable text after the gates.

Audience claims (`… to independent and mid-sized companies`) must appear in the evidence as the company's own customers. Otherwise the clause is dropped or the text is rejected. `Learn more` / `Read more` tails are stripped.

## Billing and time

**Winner-only billing:** you pay only for the hop that produced the returned text (`usage.credits.by_provider`). Rejected and lost hops cost 0. A miss costs 0.

Every path has a hard 10 s cap from request start.

## Forcing a fresh result

`company.description` and `company.domain` cache results (description: 30 days in D1; domain: short TTL in-isolate). To skip the cache read and re-run the ladder (the fresh answer is still written), send header `X-Router-Cache: bypass` (any other value returns `400 invalid_cache`), or `Cache-Control: no-cache` / `no-store`, or body `skip_cache: true`. `skip_cache` must be a boolean; non-boolean values return `400 invalid_cache`, same as a bad `X-Router-Cache` value. Reusing an `Idempotency-Key` still returns the stored response even with bypass flags. `company.resolve` ignores `X-Router-Cache: bypass` and `skip_cache`, so it may return a cached answer.

## Input

The body accepts `domain`, `website`, `email`, `name`, plus:

- `path` (or `routing.path`): `speed` \| `balance` \| `accuracy` \| `coverage`.
- `max_chars`: integer 80–500, default 300. Trims at a sentence boundary.
- `skip_cache`: boolean; non-boolean → `400 invalid_cache`.
- `external_ref`: client correlation key, echoed on the run.
- `routing`: `order`, `only`, `max_provider_credits`, `allow_fallbacks`.
- `dry_run`: no credit spend.

## Example response (`balance` hit)

```json
{
  "ok": true,
  "schema_version": "2",
  "run_id": "run_01h2example",
  "capability": "company.description",
  "es_decision": "hit",
  "answer": {
    "outcome": "hit",
    "reason_code": "exact_one",
    "es_decision": "hit",
    "confidence": "high",
    "summary": "Site probe search hit via homepage_extract",
    "identity": { "method": "jev", "score": 0.96 }
  },
  "result": {
    "description": "OutboundSync connects outbound sales engagement platforms to CRMs.",
    "source_kind": "quoted",
    "language_note": null,
    "company_domain": "outboundsync.com",
    "compose_echo": false,
    "homepage_meta_only": false,
    "flags": {
      "hype": false,
      "first_person": false,
      "tagline": false,
      "same_as_speed": false,
      "truncated": false,
      "cta": false,
      "grammar": false
    }
  },
  "usage": {
    "credits": { "cap": 2, "spent": 0, "by_provider": { "aiark": 0 } },
    "hops": [{ "provider": "aiark", "status": "lost", "credits": 0 }]
  }
}
```

## Example response (miss)

```json
{
  "ok": true,
  "schema_version": "2",
  "capability": "company.description",
  "es_decision": "miss",
  "answer": {
    "outcome": "no_decision",
    "reason_code": "no_match",
    "es_decision": "miss",
    "confidence": null,
    "summary": "No decision (no_match)",
    "identity": null
  },
  "result": {
    "description": null,
    "source_kind": null,
    "language_note": null,
    "company_domain": "example-invalid.test",
    "compose_echo": false,
    "homepage_meta_only": false,
    "flags": null
  },
  "usage": { "credits": { "cap": 2, "spent": 0, "by_provider": {} }, "hops": [] }
}
```

## Explain

Prefer `X-Router-Explain: minimal` on CRM callouts; it is an alias of the clean envelope. Use `full` when you need `trace.attempts`.

Salesforce External Services import `openapi.es.yaml` (`operationId: companyDescription`), not the full OpenAPI file. The ES response schemas accept extra fields.
