REST

Wire API v1

One JSON API for all Ajel content in ten languages. Every response carries the original link, source attribution and the editorial update date.

Base URL

All paths below are relative to the base URL.

BASEhttps://ajel.sa/api/wire
SHORThttps://wire.ajel.sa

The short domain https://wire.ajel.sa serves the same paths without the /api/wire prefix (for example /v1/latest). The official spec is OpenAPI 3.1.

Endpoints

All GET, all returning UTF-8 JSON.

MethodPathDescription
GET/v1/languagesThe ten platform languages, their sites and feeds
GET/v1/sections?language=arSections of a language edition
GET/v1/latest?language=ar&section=&limit=20Latest stories (+ cursor pagination)
GET/v1/breaking?language=arBreaking news (last 72 hours)
GET/v1/search?q=...&language=arSearch by title/summary
GET/v1/articles?language=ar&cursor=...Filtered list + pagination
GET/v1/articles/{id}One story with full text and translations
GET/v1/articles/{id}/translationsEvery language version of a story
GET/v1/topicsCurated topics (approved entities and cities)
GET/v1/topics/{slug}/articlesStories for a curated topic

Authentication and limits

  • A key is required: any request without a valid key returns401 key_required. Create your free account here.
  • Free tier: 3,000 requests/hour. Send the key in the x-api-key header or as Authorization: Bearer; never in the URL.
  • Need more? Request a higher limit from your dashboard and we review it.
  • The X-RateLimit-* headers come back with every response. Over the limit = 429.
  • CORS is open; calling straight from the browser is allowed.
curl · with key
curl -H "x-api-key: ajw_xxxxxxxx..." \
  "https://ajel.sa/api/wire/v1/latest?language=en&limit=10"

Article shape

The key fields. updated_at is the editorial update date (never earlier than publication).

JSON
{
  "id": "9b2f7c1e-....",
  "language": "ar",
  "direction": "rtl",
  "title": "عنوان الخبر",
  "summary": "الملخّص",
  "canonical_url": "https://ajel.sa/local/abc123",
  "published_at": "2026-07-24T09:00:00.000Z",
  "updated_at": "2026-07-24T09:00:00.000Z",
  "status": "published",
  "breaking": false,
  "section": { "slug": "local", "name": "المحليات" },
  "authors": [{ "name": "فريق التحرير" }],
  "media": [{ "type": "image", "url": "https://...", "reuse_allowed": false }],
  "available_translations": ["en", "ru", "tr"],
  "attribution": {
    "brand": "صحيفة عاجل",
    "text": "المصدر: صحيفة عاجل",
    "url": "https://ajel.sa/local/abc123"
  },
  "usage": {
    "republication_allowed": true,
    "attribution_required": true,
    "commercial_use_allowed": true,
    "resale_of_raw_feed_allowed": false
  }
}

Examples

Copy and paste; the key comes from your dashboard.

JavaScript
const res = await fetch("https://ajel.sa/api/wire/v1/latest?language=ar&limit=10");
const { data } = await res.json();
for (const a of data) console.log(a.title, "→", a.canonical_url);
Python
import requests
r = requests.get("https://ajel.sa/api/wire/v1/search",
                 params={"q": "الرياض", "language": "ar"},
                 headers={"x-api-key": "ajw_..."})
for a in r.json()["data"]:
    print(a["title"], a["canonical_url"])
Pagination (cursor)
# first page
curl "https://ajel.sa/api/wire/v1/articles?language=ar&limit=20"
# next page: pass pagination.next_cursor as-is
curl "https://ajel.sa/api/wire/v1/articles?language=ar&limit=20&cursor=MTc1..."

Usage rules (short version)

  • Showing “Ajel” (صحيفة عاجل) as the source with a link to the story is mandatory.
  • Text may be republished (in full or summarized) without distortion. Images need a rights check (reuse_allowed).
  • Commercial use is allowed; reselling the raw feed as a standalone source is not.

Details in the usage policy.