Content API

The Content REST API is a read-only API for delivering content from Statamic to your frontend, external apps, SPAs, and numerous other possible sources. Content is delivered as JSON data.

Pro Feature

(If you’re interested in GraphQL, we have that too.)

Enable the API

Enable the API in your config or with an environment variable.

// config/statamic/api.php
'enabled' => true,
STATAMIC_API_ENABLED=true

You will also need to enable the resources you want to be available. For security, they’re all disabled by default.

// config/statamic/api.php

'resources' => [
  'collections' => true,
  'taxonomies' => true,
  // etc
]

Endpoints

https://yourdomain.tld/api/{endpoint} You may send requests to the following endpoints:

Customizing the API URL

You may customize the route in your API config file or with an environment variable.

// config/statamic/api.php
 'route' => 'not_api',
STATAMIC_API_ROUTE=not_api

Filtering

You may filter results by using the filter query parameter.

/endpoint?filter[{field}:{condition}]={value}

You may use the conditions available to the collection tag. eg. contains, is, isnt (or not), etc. For example:

/endpoint?filter[title:contains]=awesome&filter[featured]=true

This would filter down the results to where the title value contains the string "awesome", and the featured value is true. When you omit the condition, it defaults to is.

Multi-Site

If you are using Multi-Site, the Content API serves content from all sites at once. You can limit the fetched data to a specific site with a site filter like so:

/endpoint?filter[site]=default

Sorting

You may sort results by using the sort query parameter:

/endpoint?sort=field

You can sort in reverse by prefixing the field with a -:

/endpoint?sort=-field

You may sort by multiple fields by comma separating them. The reverse flag can be combined with any field:

/endpoint?sort=one,-two,three

Selecting Fields

You may specify which top level fields should be included in the response.

/endpoint?fields=id,title,content

Pagination

Results will be paginated into 25 items per page by default. You may specify the items per page and which page you are viewing with the limit and page parameters:

/endpoint?limit=10&page=1

The response will contain your data, links to easily get next/previous URLs, and meta information for more easily creating a paginator.

{
    "data": [
        {...},
        {...},
    ],
    "links": {
        "first": "/endpoint?limit=10&page=1",
        "last": "/endpoint?limit=10&page=3",
        "prev": null,
        "next": "/endpoint?limit=10&page=2",
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "to": 10,
        "total": 29,
        "per_page": 10,
        "path": "/endpoint",
    }
}

Entries

GET /api/collections/{collection}/entries

Gets entries within a collection.

{
  "data": [
    {
      "title": "My First Day"
    }
  ],
  "links": {...},
  "meta": {...}
}

Entry

GET /api/collections/{collection}/entries/{id}

Gets a single entry.

{
  "data": {
    "title": "My First Day"
  }
}

Collection Tree

GET /api/collections/{collection}/tree

Gets entry tree for a structured collection.

{
  "data": [
    {
      "page": {
        "title": "About",
        "url": "/about"
      },
      "depth": 1,
      "children": [
        {
          "page": {
            "title": "Articles",
            "url": "/about/articles"
          },
          "depth": 2,
          "children": []
        }
      ]
    }
  ]
}

Params

On this endpoint, the fields param will allow you to select fields within each page object. You may also set a max_depth to limit nesting depth.

/api/collections/{collection}/tree?fields=title,url&max_depth=2

GET /api/navs/{nav}/tree

Gets tree for a navigation structure.

{
  "data": [
    {
      "page": {
        "title": "Recommended Products",
        "url": "https://rainforest.store/?cid=statamic",
      },
      "depth": 1,
      "children": [
        {
          "page": {
            "title": "Books",
            "url": "https://rainforest.store/?cid=statamic&type=books",
          },
          "depth": 2,
          "children": []
        }
      ]
    }
  ]
}

Params

On this endpoint, the fields param will allow you to select fields within each page object. You may also set a max_depth to limit nesting depth.

/api/navs/{nav}/tree?fields=title,url&max_depth=2

Taxonomy Terms

GET /api/taxonomies/{taxonomy}/terms

Gets terms in a taxonomy.

{
  "data": [
    {
      "title": "Music",
    }
  ],
  "links": {...},
  "meta": {...}
}

Taxonomy Term

GET /api/taxonomies/{taxonomy}/terms/{slug}

Gets a single taxonomy term.

{
  "data": {
    "title": "My First Day"
  }
}

Globals

GET /api/globals

Gets all globals.

{
  "data": [
    {
      "handle": "global",
      "api_url": "http://example.com/api/globals/global",
      "foo": "bar",
    },
    {
      "handle": "another",
      "api_url": "http://example.com/api/globals/another",
      "baz": "qux",
    }
  ],
}

Global

GET /api/globals/{handle}

Gets a single global set’s variables.

{
  "data": {
    "handle": "global",
    "api_url": "http://example.com/api/globals/global",
    "foo": "bar",
  }
}

Users

GET /api/users

Get users.

{
  "data": [
    {
      "id": "1",
      "email": "[email protected]",
      "api_url": "http://example.com/api/users/1"
    }
  ],
  "links": {...},
  "meta": {...}
}

User

GET /api/users/{id}

Get a single user.

{
  "data": {
    "id": "1",
    "email": "[email protected]",
    "api_url": "http://example.com/api/users/1"
  }
}

Assets

GET /api/assets/{container}

Get a container’s asset data.

{
  "data": [
    {
      "id": "main::foo.jpg",
      "url": "/assets/foo.jpg",
      "api_url": "http://example.com/api/assets/main/foo.jpg"
    }
  ],
  "links": {...},
  "meta": {...}
}

Asset

GET /api/assets/{container}/{path}

Get a single asset’s data.

The path in the URL should be the relative path from the container’s root.

{
  "data": {
    "id": "main::foo.jpg",
    "url": "/assets/foo.jpg",
    "api_url": "http://example.com/api/assets/main/foo.jpg"
  }
}

Customizing Resources

By default the resources generally use the item’s Augmented data.

You are free to override the resource classes with your own, in turn letting you customize the responses.

In a service provider, use the map method to define the overriding resources:

use App\Http\Resources\CustomEntryResource;
use Statamic\Http\Resources\API\Resource;
use Statamic\Http\Resources\API\EntryResource;

class AppServiceProvider extends Provider
{
    public function boot()
    {
        Resource::map([
            EntryResource::class => CustomEntryResource::class,
        ]);
    }
}
<?php

namespace App\Http\Resources;

use Statamic\Http\Resources\API\EntryResource;

class CustomEntryResource extends EntryResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->resource->id(),
            'title' => $this->resource->value('title'),
        ];
    }
}

Caching

API responses are cached by default. You may customize the cache expiry in config/statamic/api.php.

'cache' => [
    'expiry' => 60,
],

Cache Invalidation

Cached responses are automatically invalidated when content is changed. Depending on your API usage and blueprint schema, you may also wish to ignore specific events when invalidating.

'cache' => [
    'expiry' => 60,
    'ignored_events' => [
        \Statamic\Events\UserSaved::class,
        \Statamic\Events\UserDeleted::class,
    ],
],

Disabling Caching

If you wish to disable caching altogether, set cache to false.

'cache' => false,

Custom Cache Driver

If you need a more intricate caching solution, you may reference a custom cache driver class and pass extra config along if necessary.

'cache' => [
    'class' => CustomCacher::class,
    'expiry' => 60,
    'foo' => 'bar',
],

Be sure to extend Statamic\API\AbstractCacher and implement the required methods. You can access custom config via the config() method, ie. $this->config('foo').

use Statamic\API\AbstractCacher;

class CustomCacher extends AbstractCacher
{
    public function get(Request $request)
    {
        //
    }

    public function put(Request $request, JsonResponse $response)
    {
        //
    }

    public function handleInvalidationEvent(Event $event)
    {
        //
    }
}

Authentication

Coming soon. There are no native access tokens or other common authentication methods ready to use. Yet.

Betterify this page on Github!