Every Laravel team that has shipped a standards-compliant API knows the tax: a third-party package like laravel-json-api/laravel, its config files, a custom schema directory, and hundreds of lines of glue code holding the response format together. Laravel 13 moves that entire layer into the framework, behind resource classes that look almost exactly like the Eloquent API Resources every Laravel developer already knows. For teams running those packages today, the migration is mostly deletion — though as with any format swap consumed by mobile clients, you'll want contract tests proving the output matches before anything ships.
That's the practical story behind one of Laravel 13's headline features. The release, which shipped on March 17, 2026, requires PHP 8.3 or higher and introduces no breaking changes to application code (Laravel News). Tucked in alongside the usual quality-of-life improvements is first-party JSON:API support: new resource classes that handle response serialization, relationship inclusion, sparse fieldsets, links, and compliant response headers automatically (PHP Everyday). Before this, standards-compliant APIs in Laravel meant third-party packages or a lot of hand-rolled convention documents that every new hire had to absorb.
One caveat before the code: the samples below reflect the API surface as described in release coverage and our early usage. Exact class and method names can shift between minor releases, so treat them as the shape of the feature and confirm against the official docs for your installed version.
We provision and deploy a lot of Laravel APIs at Deploynix, so we've spent real time with the new JSON:API layer since the release. This post covers what the specification buys you, how the new resource classes compare to classic Eloquent API Resources, how to handle includes and sparse fieldsets without wrecking your query count, and what changes at the server level when you take a compliant API to production.
Why Does JSON:API Compliance Matter for a Laravel API?
JSON:API is a specification for building HTTP APIs in JSON, maintained at jsonapi.org. It defines the shape of every response your API returns: how resources are structured, how relationships are expressed, how errors are formatted, how clients request related data, and how pagination links are exposed. In other words, it answers all the questions your team currently answers in a Notion doc titled "API Conventions" that nobody has updated since 2024.
That sounds bureaucratic until you've maintained an API consumed by more than one client. Every unspecified decision becomes a negotiation. Should errors be {"error": "..."} or {"errors": [...]}? Are timestamps ISO 8601 or Unix epochs? Does the mobile team get a slimmed-down payload, or do they download the full resource and throw most of it away over a cellular connection? Multiply those debates across five endpoints and three client teams and you've burned a sprint on formatting.
Compliance pays off in three concrete ways. First, client tooling: because the document structure is standardized, generic JSON:API client libraries exist for TypeScript, Swift, Kotlin, and most other client-side ecosystems, so frontend teams deserialize your responses without writing bespoke mapping code. Second, standardized errors: the spec's errors array with status, title, detail, and source.pointer members means validation failures render identically everywhere, and client error handling gets written once. Third, sparse fieldsets: clients ask for exactly the attributes they need, which trims payloads meaningfully for list endpoints on mobile networks.
What a compliant response actually looks like
Here's a minimal JSON:API document for a single article with its author included:
{
"data": {
"type": "articles",
"id": "42",
"attributes": {
"title": "Zero-downtime deploys, explained",
"published_at": "2026-07-14T09:30:00+00:00"
},
"relationships": {
"author": {
"data": { "type": "users", "id": "7" }
}
},
"links": {
"self": "https://api.example.com/v1/articles/42"
}
},
"included": [
{
"type": "users",
"id": "7",
"attributes": { "name": "Rana Farouk" }
}
]
}
Every resource carries a type and a string id. Relationships are expressed as linkage objects rather than nested blobs, and related resources travel in a top-level included array so each one appears exactly once, no matter how many resources reference it. Responses are served with the application/vnd.api+json media type. None of this is hard to produce by hand. It's just tedious, and tedious formats drift. A framework-level implementation is what keeps them from drifting.
What Ships in Laravel 13 for JSON:API?
Laravel 13's contribution is a set of resource classes that sit next to the classic JsonResource family. Extend the JSON:API base class instead of the classic one and the framework takes over the spec's mechanical obligations: it wraps your data in the correct document structure, resolves include query parameters into the included array, applies fields[type] sparse fieldsets, generates self and pagination links, and sets the application/vnd.api+json content type on the way out (PHP Everyday).
Because Laravel 13 has no application-code breaking changes (Laravel News), your existing classic resources keep working untouched. The JSON:API classes are additive. That matters for adoption: you can upgrade the framework first, then move endpoints to the new resources one route group at a time. If you haven't done the framework upgrade yet, we walked through the mechanics in upgrading to Laravel 13 in production with zero downtime, and the short version is that this is the calmest major upgrade since Laravel 10.
The new resource classes at a glance
A JSON:API resource looks like a classic resource that's been split into intent-revealing methods. Instead of one toArray() returning everything, you declare attributes, relationships, and links separately, and the framework assembles the document:
php
Top comments (0)