One async path operation — signed articles land there.
FastAPI receives the content; your app renders or serves it. The recipe is a single async path-operation function — await request.body() gives you the raw bytes for the HMAC check, hmac.compare_digest verifies it, and you store the post. No extra dependency beyond fastapi and uvicorn.
| Connection | A path-operation function — @app.post("/webhook"), recipe provided |
|---|---|
| Security | HMAC-signed + timestamped — hmac.compare_digest over ${timestamp}.${rawBody}, replay-window protected |
| Payload | Full article JSON — title, HTML, images, meta, slug, language |
| Images | DraftSEO CDN URLs — URLs ride in the payload; rehost to your own storage if you prefer |
| Framework fit | Fully async — await request.body() for the exact bytes; return quickly |
Who does what
Add the async path operation, verify the HMAC over await request.body(), then persist the post with your ORM. After the green test, zero effort per article.
Your Pydantic models and DB layer stay entirely yours.
Setup
Connect a site → FastAPI. You get a signing secret and the path-operation recipe.
~1 minute
Paste the @app.post handler, await the raw body, verify the signature and store the post — the recipe walks it through.
~10 minutes
DraftSEO sends a signed test event; a green check confirms the handshake.
~1 minute
Every generated article is delivered to your endpoint on cadence.
Ongoing · zero clicks
FAQ
A JSON body { event, deliveryId, data } — data holds the title, HTML article, slug, language, meta fields and image URLs, so one json.loads yields a complete post.
Each request is HMAC-signed over ${timestamp}.${rawBody} with a timestamp header; you recompute it with hmac.new and compare using hmac.compare_digest, rejecting anything past the 5-minute replay window.
Yes — the recipe is an async def path operation, so you can await request.body() for the raw bytes and await your database writes. Verify the signature first, then do the work.
No card required. Signed test delivery in under a minute.