Thanks to visit codestin.com
Credit goes to github.com

Skip to content

spatie/freek.dev

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2,299 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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 status
  • original_content (0 or 1): filter by original content
  • tag (string): filter by tag name
  • search (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.