chapter-three/apple-news-api
A Laravel package for integrating with the Apple News Publisher API. It provides a fluent interface for creating and publishing articles, managing channels and sections, handling signed requests, and automating content workflows, simplifying Apple News publishing in Laravel applications.
composer require chapter-three/apple-news-api. There is no Laravel service provider; the library is plain PHP, so you instantiate classes yourself (or bind them in a ServiceProvider/container binding for injection).config/services.php (or a dedicated config/apple-news.php) and read them via env().Client class (the API transport wrapper, typically ChapterThree\AppleNewsAPI\Client) for the publish/read/update/delete methods, and at the Document / Article namespace for the JSON builder. Those are the two halves of the package: transport and document model.use ChapterThree\AppleNewsAPI\Client;
use ChapterThree\AppleNewsAPI\Document\Article;
use ChapterThree\AppleNewsAPI\Document\Components\Body;
$client = new Client(
config('services.apple_news.key_id'),
config('services.apple_news.key_secret'),
config('services.apple_news.channel_id')
);
$article = new Article();
$article->setTitle('Hello Apple News');
$article->addComponent(new Body('First paragraph…'));
$response = $client->publishArticle($article);
$articleId = $response->getId();
App\AppleNews\ArticleBuilder) rather than sprinkling addComponent() calls across controllers — Apple News JSON gets deep quickly and you want a single place that owns the shape.Body, Heading, Image, Quote, Caption, etc.) and addComponent() on containers. Nesting works by adding child components to a container component, matching the Apple News JSON hierarchy (containerComponents / components).publication and publish_date on the Article before publishing. The API rejects documents missing required fields, and the failure is often a generic 400 — set metadata up front and add components after.$article = (new ArticleBuilder())->fromModel($post); // title, authors, dates
$article->addComponent((new Heading($post->title))->setRole('title'));
$article->addComponent(new Body($post->body_html));
$client->publishArticle($article);
Persist the returned Apple News article ID and revision on the model — you need both for every subsequent update.
PublishToAppleNews::dispatch($post)). Use retry and a unique job constraint so a saved-post event doesn't double-publish. Fire an ArticlePublished event on success so other listeners (Slack, analytics) can react.revision from the last read. Pattern: readArticle($id) → mutate document → updateArticle($id, $document, $revision). Store revisions in a column; they increment on every successful write.new Client(...) scattered throughout the codebase."php": "^8.x" overrides in composer.json or pin to a PHP version the package was tested on. If you hit fatal errors, that's the cause, not your code.date on the box; a few hundred seconds off will break HMAC signing.202 Accepted is not "published". The create endpoint returns 202, and the article may not be readable immediately. Do not assert on read-after-write in tests; poll or ignore for a few seconds in production.HandlerStack with request/response middleware during local development. Without it, you're debugging an opaque 400.getConfig()/serialization on Article for document-level flags rather than patching vendor code.composer update will otherwise silently revert your fix.How can I help you explore Laravel packages today?