We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.
Blog Posts API
The site exposes a REST API at /api/posts for programmatic blog post management (e.g. by an AI tool). It is protected by Sanctum token authentication and restricted to admin users.
Authentication
All requests require a Bearer token in the Authorization header.
Authorization: Bearer <token>
To create a token, run this in tinker:
$user = User::where('admin', true)->first();
$token = $user->createToken('ai-tool');
$token->plainTextToken; // save this, it's only shown once
Endpoints
List posts
GET /api/posts
Query parameters (all optional):
published(0 or 1): filter by published statusoriginal_content(0 or 1): filter by original contenttag(string): filter by tag namesearch(string): search posts by title
Returns paginated results.
Get a post
GET /api/posts/{id}
Create a post
POST /api/posts
Body (JSON):
title(string, required)text(string, required, markdown)publish_date(ISO 8601 date, nullable)published(boolean, default false)original_content(boolean, default false)external_url(URL string, nullable)tags(array of strings)send_automated_tweet(boolean, default false)author_twitter_handle(string, nullable)series_slug(string, nullable)
Returns 201 with the created post.
Update a post
PUT /api/posts/{id}
Same fields as create, all optional. Only send fields you want to change.
Delete a post
DELETE /api/posts/{id}
Returns 204 No Content.
Response format
All responses are wrapped in a data key:
{
"data": {
"id": 1,
"title": "...",
"slug": "...",
"text": "...",
"html": "...",
"publish_date": "2026-03-02T14:00:00+00:00",
"published": true,
"original_content": false,
"external_url": null,
"series_slug": null,
"author_twitter_handle": null,
"send_automated_tweet": false,
"tags": ["laravel", "php"],
"url": "https://freek.dev/1-post-slug",
"preview_url": "https://freek.dev/1-post-slug?preview_secret=abc123",
"created_at": "2026-03-02T12:00:00+00:00",
"updated_at": "2026-03-02T12:00:00+00:00"
}
}
Contributing
Please see CONTRIBUTING for details.
Security
If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.
Postcardware
You're free to use this code (it's MIT-licensed). If you use it to set up your own blog we would highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.
Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.
All postcards are published on our website.
Credits
License
The MIT License (MIT). Please see License File for more information.
