Delivery API
Suprafața publică, fără autentificare, care servește conținutul tău
publicat. Totul e indexat după cheia publică a site-ului tău (pk_…) și
funcționează doar pentru site-uri verificate. GET
și HEAD sunt suportate peste tot.
Originea de bază: https://api.dailysmith.com.
Pagini randate
GET /v1/render/{publicKey}/{path}
{path} e calea așa cum apare pe site-ul tău — ex. /blog pentru
index, /blog/my-post-slug pentru un articol. baas rezolvă ce blog deține
calea după calea lui de bază, deci proxy, SDK și prerender folosesc toate
aceeași schemă de URL-uri.
| Parametru query | Sens |
|---|---|
format=fragment | Fragment JSON pentru SDK, în loc de o pagină HTML completă |
page=N | Paginare index (10 articole per pagină) |
O pagină randată e servită întotdeauna în limba
blogului ei — aici nu există parametru locale. Un blog are o singură limbă,
așa că singurul lucru pe care l-ar putea produce altă valoare e o pagină goală
care declară o limbă în care nu are nimic, și asta nu merită dată unui crawler.
Dacă publici într-o a doua limbă, fă un al doilea blog. Listarea structurată de
mai jos acceptă locale, pentru că acolo un răspuns gol explicit la „aveți
ediție în germană?" chiar folosește.
Paginile complete sunt documente HTML complete, cu titlu, meta
descriere, taguri Open Graph și Twitter card (inclusiv og:image, când
articolul are o imagine reprezentativă), URL
canonical, JSON-LD, un stil implicit lizibil și paleta ta de
temă inline.
Fragmentele (format=fragment) returnează:
{
"html": "<article class=\"baas-post\">…</article>",
"kind": "post",
"title": "Titlul articolului",
"description": "Meta descriere",
"canonical": "https://example.com/blog/my-post-slug",
"json_ld": "{…}",
"locale": "en",
"og_locale": "en_US",
"css": "/* paleta de temă a blogului, doar când una e setată */",
"css_href": "/v1/sdk/md2.css",
"hero_image_url": "https://api.dailysmith.com/v1/media/01a01789-959f-78f7-a5d0-78fc208903f6",
"hero_image_alt": "Ilustrație abstractă pentru Titlul articolului",
"hero_image_width": 1376,
"hero_image_height": 768
}
locale e limba blogului ca tag simplu — pune-o pe
elementul în care inserezi fragmentul, altfel articolul e anunțat de cititorul
de ecran în limba pe care o declară pagina ta. og_locale e aceeași limbă în
forma limbă_TERITORIU pe care o cere Open Graph; setează-l ca
<meta property="og:locale">, altfel cardul de distribuire e presupus
en_US. SDK-ul nostru pune întotdeauna lang pe fragmentul pe care îl
inserează, iar og:locale îl setează și pe el, dacă nu ai renunțat la
gestionarea head-ului.
Cele patru câmpuri hero_image_* sunt omise complet pentru un articol
fără imagine reprezentativă, adică fiecare articol
scris înainte să le activezi. Imaginea e și deja în interiorul html-ului,
ca <img class="baas-hero"> — un singur motor de randare servește fiecare
mod de livrare, deci o obții gratis doar prin inserarea fragmentului.
Câmpurile separate există ca să poți construi un card social sau o miniatură
de listare fără să parsezi marcajul; propriul nostru SDK le citește ca să
seteze og:image și le curăță din nou când navighează către un articol care
nu are una. Imaginea e servită de la https://api.dailysmith.com/v1/media/{id} —
permanentă, imuabilă și publică după id, deci nu are nevoie de nicio cheie
și poate fi pusă în cache pentru totdeauna.
css și css_href sunt omise amândouă când nu se aplică, nu trimise
goale: css poartă doar paleta de temă a blogului —
niciodată foaia de stil a componentelor — deci lipsește când nu există o
temă activă; css_href indică spre foaia de stil comună, cacheable, de mai
jos, și e prezent doar când conținutul chiar folosește componente MD2.
Paginile complete le inline-uiesc pe amândouă, în loc să le lege. Pentru
index (kind: "index"), description și json_ld sunt mereu șiruri
goale, nu omise.
Listări structurate
GET /v1/delivery/{publicKey}/blogs
GET /v1/delivery/{publicKey}/posts?base_path=/blog&locale=en&page=1
blogs listează blogurile site-ului (nume, cale de bază, locale implicit).
posts listează articolele publicate pentru un blog — slug, titlu,
rezumat, cale pe site, dată de publicare, minute de citire — paginat
(răspunsul poartă și page și total_pages) — utile ca să-ți construiești
propriul UI de index sau să alimentezi alte sisteme.
Fluxuri
GET /v1/delivery/{publicKey}/sitemap.xml
GET /v1/delivery/{publicKey}/rss.xml
Sitemap-ul acoperă indexurile de blog și fiecare articol publicat, cu date
de ultima modificare; RSS-ul poartă cele mai recente 50 de articole.
Referențiază sitemap-ul din robots.txt-ul tău:
Sitemap: https://api.dailysmith.com/v1/delivery/pk_YOUR_KEY/sitemap.xml
Scriptul SDK
GET /v1/sdk/blog.js
GET /v1/sdk/md2.css
JS SDK-ul și foaia de stil pentru conținut bogat MD2
spre care indică css_href-ul unui fragment — ambele servite cu headere de
cache pe termen lung.
Erori
Fiecare eroare e problem+json (RFC 9457):
{ "type": "about:blank", "title": "Not found", "status": 404, "detail": "…" }
| Unde | Status | detail | Sens |
|---|---|---|---|
| Orice endpoint | 404 | unknown or unverified site key | Cheia nu există, sau site-ul nu a trecut de verificare — indistincte intenționat, ca o cheie să nu poată fi folosită ca să sondezi ce site-uri există. |
/v1/render/{publicKey}/{path} | 404 | no blog is mounted at this path | Niciun blog nu are calea de bază potrivită cu {path}. |
/v1/render/{publicKey}/{path} | 404 | no such post | Calea a rezolvat un blog, dar slug-ul nu. |
/v1/delivery/{publicKey}/posts | 404 | no blog at that base path | Parametrul query base_path nu se potrivește cu niciun blog. |
/v1/sdk/md2.css | 503 | stylesheet temporarily unavailable | Sidecar-ul de randare e inaccesibil — reîncearcă. |
Nimic pe această suprafață nu returnează vreodată 402 sau 422 — erorile de cotă și de validare se aplică doar API-ului autentificat de conținut.
Semantica de cache
- Fiecare răspuns poartă un ETag puternic (un hash al conținutului) și
respectă
If-None-Matchcu304 Not Modified. Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600— prietenos cu CDN-urile și cu cache-ul tău de edge; schimbările de conținut (un articol nou, o temă editată) schimbă ETag-ul.- CORS e complet deschis (
Access-Control-Allow-Origin: *): conținutul e public prin definiție, ceea ce îi permite SDK-ului să-l preia de pe domeniul tău.