Notion SDK for PHP
PHP version of the official NOTION API. It works the same way as the reference JavaScript SDK 🎉
Install this package as a dependency using Composer.
composer require brd6/notion-sdk-phpThis package (brd6/notion-sdk-php) is not tied to any specific library such as Guzzle or Buzz that sends HTTP messages. Instead, it uses the PSR-18 client abstraction to let users choose whichever PSR-7 implementation
and HTTP client they want to use.
If you just want to get started quickly with symfony http client, run the following command:
composer require brd6/notion-sdk-php symfony/http-client nyholm/psr7Use Notion's Getting Started Guide to get set up to use Notion's API.
Import and initialize a client using an integration token or an OAuth access token.
use Brd6\NotionSdkPhp\Client;
use Brd6\NotionSdkPhp\ClientOptions;
$options = (new ClientOptions())
->setAuth(getenv('NOTION_TOKEN'));
$notion = new Client($options);Make a request to any Notion API endpoint.
See the complete list of endpoints in the API reference.
$listUsersResponse = $notion->users()->list();
var_dump($listUsersResponse->toArray());array (size=4)
'has_more' => boolean false
'results' =>
array (size=2)
0 =>
array (size=6)
'object' => string 'user' (length=4)
'id' => string '7f03dda0-a132-49d7-b8b2-29c9ed1b1f0e' (length=36)
'type' => string 'person' (length=6)
'name' => string 'John Doe' (length=8)
'avatar_url' => string 'https://s3-us-west-2.amazonaws.com/public.notion-static.com/521dfe9c-f821-4de8-a0bb-e40ff71283e5/39989484_10217003981481443_4621803518267752448_n.jpg' (length=149)
'person' =>
array (size=1)
...
1 =>
array (size=5)
'object' => string 'user' (length=4)
'id' => string '8dee9e49-7369-4a6d-a11f-7db625b2448c' (length=36)
'type' => string 'bot' (length=3)
'name' => string 'MyBot' (length=5)
'bot' =>
array (size=1)
...
'object' => string 'list' (length=4)
'type' => string 'user' (length=4)Endpoint parameters are grouped into a single object. You don't need to remember which parameters go in the path, query, or body.
$databaseRequest = new DatabaseRequest();
$databaseRequest->setFilter([
'property' => 'Landmark',
'text' => [
'contains' => 'Bridge',
],
]);
$myPage = $notion->databases()->query('897e5a76-ae52-4b48-9fdf-e71f5945d1af', $databaseRequest)If you use Notion API version 2025-09-03 or newer, the SDK supports data source endpoints via $notion->dataSources(), and page creation with data_source_id parents. When creating a database with this API version, databases()->create() automatically maps properties to the required initial_data_source payload.
The SDK supports the Notion File Upload API via $notion->fileUploads(). Uploading a file takes one call — Notion derives the content type from the filename:
$fileUpload = $notion->fileUploads()->upload($contents, 'image.png');The uploaded file can then be referenced from a block, page icon, or cover. For larger files and imports, the underlying operations are exposed directly:
use Brd6\NotionSdkPhp\Resource\FileUpload\FileUploadRequest;
// import from a public HTTPS URL
$fileUpload = $notion->fileUploads()->create(FileUploadRequest::externalUrl('https://example.com/image.png'));
// multi-part upload (paid workspaces): create, send each part, then complete
$fileUpload = $notion->fileUploads()->create(FileUploadRequest::multiPart(2, 'large.txt'));
$notion->fileUploads()->sendPart($fileUpload->getId(), $firstChunk, 1, 'large.txt');
$notion->fileUploads()->sendPart($fileUpload->getId(), $secondChunk, 2, 'large.txt');
$fileUpload = $notion->fileUploads()->complete($fileUpload->getId());retrieve() and list() expose upload status. See examples/09-file-uploads-api-smoke for the full flow, including attaching the upload to a page as an image block.
If the API returns an unsuccessful response, an ApiResponseException will be thrown.
The error contains properties from the response, and the most helpful is code. You can compare code to the values in the NotionErrorCodeConstant object to avoid misspelling error codes.
The Client supports the following options on initialization. These options can be set on the ClientOptions instance.
| Option | Default value | Type | Description |
|---|---|---|---|
auth |
'' |
string |
Bearer token for authentication. If left undefined, the auth parameter should be set on each request. |
timeout |
60 |
number |
Number of seconds to wait before throw a RequestTimeoutException |
baseUrl |
"https://api.notion.com" |
string |
The root URL for sending API requests. This can be changed to test with a mock server. |
httpClient |
Default Http Client | Psr\Http\Client\ClientInterface |
The Http Client used to make request on the Notion API. This can be change to customize the base Http Client or replace with a mocked Http Client. |
The examples/ directory contains a comprehensive set of usage examples that demonstrate how to use the SDK for various tasks, from basic API calls to complex integrations:
- 01-intro-to-notion-api - Basic database queries and page creation
- 02-parse-text-from-any-block - Extract text content from all block types
- 03-web-form - Web form to Notion page integration
- 04-generate-random-data - Populate databases with sample data
- 05-notify-on-update - Email notifications for database changes
- 06-notion-github-sync - GitHub issues synchronization
- 07-oauth-flow - Complete OAuth 2.0 implementation
- 08-data-sources-api-smoke - Data source integration checks for retrieve/query/search/create/update
- 09-file-uploads-api-smoke - File upload via raw multipart requests, attached to a page as an image block
Each example is self-contained with its own dependencies, documentation, and setup instructions.
Contributions are welcome! To contribute, please familiarize yourself with CONTRIBUTING.md.
The MIT License (MIT). Please see LICENSE for more information.
