Aurith

The shape of it.

Everything you would be integrating against, written out before you pay for it. One endpoint for items, five for everything else, and a bearer token in the header.

Getting a key

Pay, and the key is on the next page.

Pick a key on Services. Stripe takes the payment on its own page — Aurith never sees a card — and you are returned to a page showing your key. It is shown once. Only a hash of it is stored, so it cannot be sent to you again; opening that page a second time mints a new key and turns the old one off.

Send it as Authorization: Bearer <key>, never in the query string, where it would end up in every proxy log between you and here. GET /v1/key tells you what your key carries, and GET /v1/portal hands back a Stripe link for the card, the invoices and cancelling.

Asking

One endpoint.

Items, newest first, with everything else expressed as a filter. Authentication is a bearer token in the header — never in the query string, where it would end up in every proxy log between you and here.

Request
GET https://api.aurith.ca/v1/items
  ?lang=en,pa
  &source=fed_press,eia_today
  &since=2026-08-31T04:00:00Z
  &fields=id,headline,body,source,published_at,held_at
  &cursor=itm_20260831T035901_1b77e0
  &limit=50

Authorization: Bearer your-key
Accept: application/json
Response
{
  "items": [
    {
      "id": "itm_20260831T041233_8f2a1c",
      "lang": "en",
      "headline": "Refinery outage takes a Gulf Coast crude unit offline",
      "body": "An unplanned outage has taken the main crude unit…",
      "source": "eia_today",
      "source_name": "US Energy Information Administration",
      "published_at": "2026-08-31T04:12:33Z",
      "held_at": "2026-08-31T04:15:31Z",
      "written_at": "2026-08-31T04:15:47Z",
      "latency_seconds": 178,
      "subjects": ["crude", "refining", "united-states"]
    }
  ],
  "next": "itm_20260831T035901_1b77e0",
  "held": 50
}

Body truncated above for the page. The real field carries the whole article.

Paging. next is the cursor for the page after this one — send it back as cursor. It is null when the page did not fill, which is how you know you are current. since filters on held_at, the clock the feed is ordered by, so a poll cannot be pushed off the top by a publisher re-listing something from 2009.

Fields

What comes back, and what it means.

FieldTypeWhat it is
idstringStable and sortable. Lexicographic order is chronological order.
langstringThe language this copy is written in. One item, one language, one object.
headlinestringAurith's headline, not the publisher's.
bodystringThe full article, written by Aurith.
sourcestringThe exact key from the Sources page. Filter on this.
source_namestringThe publisher, spelled out for display. This is the credit.
published_atRFC 3339When the publisher released it, as they stamped it. UTC.
held_atRFC 3339When Aurith had it. Both clocks ship so you can measure us.
written_atRFC 3339When Aurith finished writing this article. This is the moment it became available to you.
latency_secondsintegerThe difference between the first two above. Convenience, not a separate fact.
subjectsstring[]What the item is about. Coarse on purpose.

Ask for fewer. The fields parameter is a whitelist and it is honoured — request four fields and four is what crosses the wire. On a feed you are polling continuously that is the difference between a bill and a problem.

Languages

Codes.

CodeLanguageWhen
enEnglishAt launch
frFrançaisAt launch
esEspañolAt launch
paਪੰਜਾਬੀ — PunjabiAt launch
hiहिन्दीAt launch
deDeutschTo follow
ptPortuguêsTo follow
itItalianoTo follow
nlNederlandsTo follow
ja日本語To follow
ko한국어To follow
zh简体中文To follow
When it goes wrong

Errors say what to do about them.

StatusMeansDo
400A parameter is not one this endpoint knows.The response names the parameter. Fix and resend.
401No key, or a key that is not current.Check the header. Never retry a 401 in a loop.
429Over the rate for your account.Wait the seconds in Retry-After. It is always present.
5xxOur fault.Retry with backoff. since means you lose nothing by waiting.

The rate. A basic key is 10 requests a minute, a starter key 30, a full key 120. Measured over a sliding minute, per key. Over it you get a 429 and a Retry-After in seconds, always. Ask for a higher rate and say what for — it is a number in a file, not a tier.

Basic keys are released, not live. A basic key reads every source, in English only, and sees what Aurith had written before the latest of three daily releases: 9:00, 14:30 and 19:30 Toronto time. Between releases the newest items wait for the next one, so polling harder in between returns nothing new. Starter and full keys are live.

Also

Five that return no items.

Everything you need to build a filter, and one way to ask whether the feed is alive that is not polling it harder. Same key, same header.

EndpointWhat it gives
GET /v1/keyWhat your key carries: tier, rate, languages, sources, expiry, and releases — the Toronto release times, ["09:00", "14:30", "19:30"], for a basic key; null for any other.
GET /v1/sourcesEvery source key, the publisher it credits, and whether it is yours.
GET /v1/languagesThe codes, and which of them your key carries.
GET /v1/statusHow many items are held, and how long since the newest. Counts and clocks, no diagnosis.
GET /v1/portalA Stripe link for your card, your invoices and cancelling. Aurith hosts none of that.
Not in the response

Two fields that do not exist.