Skip to main content
A card is stored as JSON. doubleshift validates that JSON before serving it and renders it into one fixed HTML template. The delivery API returns either form, or both, through the format parameter of GET /v1/fragment: The Cloudflare edge library asks for json and builds the same HTML at the edge, byte for byte unless its deliveryCode option is on.

Example

A card shortened from one doubleshift generated from Volotea’s public media kit, for illustration. It is written in French: the renderer prints text as supplied. In llm_friendly_context, each \n becomes a line break.
volotea.json

JSON fields

Every field is required. The root, card and source are JSON objects, not null or arrays. A non-empty string still has characters once leading and trailing whitespace is trimmed; validation checks this without changing the value. Properties outside this table are dropped from the validated card, not refused. The URL check does not fetch the destination. The stored card has no character, byte or keyword limit; the edge library refuses a JSON answer over 64 KiB (invalid_card, too_large). A card whose stored JSON fails validation is not served: the endpoint answers no-fill (204). Cards are generated in the console from a URL, a PDF or structured text, or filled in by hand (cards); the result is always this JSON.

How the fields become HTML

The template always produces one <article class="abc-card">, in this order: the brand label, the title, the summary, the context block, then the source links. What the renderer guarantees:
  • A fixed template. Card fields fill its text and links. They cannot replace the template or add styles.
  • Escaped text. In every field and link, &, <, >, " and ' become HTML entities: markup entered in a field displays as text.
  • Absolute http(s) links only. Validation refuses any other URL; if the renderer ever receives one, it prints the link label as plain text.
  • Inline styles. The card carries its own styles and a maximum width of 680 pixels. Your page’s CSS can still affect it: the card is not an isolated document.
  • No script, no iframe, no ARIA role. The card keeps the implicit role of article.
  • The delivery number as an attribute only. A card served by the delivery API carries that call’s X-Request-Id in data-ds-delivery on its root. It is never printed as text. Console previews carry none.
  • No rewriting. The renderer does not translate, summarise or generate text. The translated_ field names describe content prepared before rendering.
A keywords line appears in the card only when it is part of llm_friendly_context, as in the example.

What your integration adds

The card stops at </article>. Your publisher edge places it before the article and adds a disclosure line as the article’s first paragraph, only when a card is served. Why both go there: where the card lands; how each edge does it: integrate. The edge library writes the disclosure line in French, or in English when the page’s <html lang> starts with en; its language option can force either:
Disclosure line
With the library’s deliveryCode option, the last six characters of the delivery number are also printed twice: after the brand on the card’s label, Brand · Volotea · ref. abcd12 in both languages; and before the final period of the disclosure line, Volotea (ref. abcd12). or Volotea (réf. abcd12).. See options.