Appearance
Facebook Stories API from Meta
Updated: May 6, 2026
This document shows you how to use the Facebook Stories API to publish Stories on Facebook Pages.
To publish a story, your app will perform the following steps:
- Upload your app user's media to the Meta servers
- Publish the media to your app user's Page as a Story
Before you start
This guide assumes you have read the Pages API Overview and implemented the needed components, and successfully completed the Get Started guide.
- You will need to implement Facebook Login or Facebook Login for Business to ask your app users for permissions needed to access their Facebook Pages and to receive Page access tokens.
- Your app users will need to be able to perform the
CREATE_CONTENTtask on the Page represented in the Page access token and give your app the following permissions:pages_manage_postspages_read_engagementpages_show_list
If you are using a business system user in your API requests, the business_management permission is also required.
Media requirements
You must provide a photo or video that fit the following specifications.
Photo specifications
| Property | Specification |
|---|---|
| File type | .jpeg, .bmp, .png, .gif, .tiff |
| File size | Files can not exceed 10MB. For .png files, we recommend not exceeding 1MB or the image may appear pixelated. |
Video specifications
| Property | Specification |
|---|---|
| File Type | .mp4 (recommended) |
| Aspect Ratio | 9 x 16 |
| Resolution | 1080 x 1920 pixels (recommended). Minimum is 540 x 960 pixels |
| Frame Rate | 24 to 60 frames per second |
| Duration | 3 to 90 seconds. A reel published as a story on a Facebook Page can not exceed 60 seconds. |
| Video Settings | * Chroma subsampling 4:2:0 * Closed GOP (2-5 seconds) * Compression – H.264, H.265 (VP9, AV1 are also supported) * Fixed frame rate * Progressive scan |
| Audio Settings | * Audio bitrate – 128kbs+ * Channels – Stereo * Codec – AAC Low Complexity * Sample rate – 48kHz |
Limitations
- A photo or video uploaded for a story can not have been used in a previously published post
- A video story can not exceed 60 seconds
- To include archived stories in your
GETrequests to see a list of your stories, you must turn your Facebook story archive on
Best practices
When testing an API call, you can include the access_token parameter set to your access token. However, when making secure calls from your app, use the access token class.
Code examples within this document are formatted for readability. Replace bold, italics values, such as page_id, with your values.
Video stories
To publish a video story on a Facebook Page, you will initialize a video upload session with Meta servers, upload the video to Meta servers, then publish the video story.
Step 1: Initialize session
To initialize an upload session, send a POST request to the /page_id/video_stories endpoint, where page_id is the ID for your Facebook Page, with the upload_phase parameter set to start.
Example request
curl -X POST "https://graph.facebook.com/v25.0/page_id/video_stories" \
-d '{
"upload_phase":"start",
}'On success, your app receives a JSON response with the ID for the video and the Facebook URL where you will be uploading the video.
Example response
{
"video_id": "video_id",
"upload_url": "https://rupload.facebook.com/video-upload/v25.0/video_id",
}Step 2: Upload a video
Now that you have initialized an upload session and received the upload URL, you can upload your video. You can upload either:
- a hosted video file on a public facing http/https server, such as a CDN
- a local video file from your device
Upload a hosted file
To upload a hosted file, send a POST request to the upload_url endpoint you received in the initialization step with the following parameters:
file_urlset to the URL for your video file
Be sure the host is rupload.facebook.com.
The API will now reject files hosted on sites that restrict access via robots.txt. Developers need to ensure that the hosting site allows the "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)" user agent to fetch the hosted file.
Files hosted on Meta CDN (e.g.. fbcdn URLs) will get rejected. Instead, developers can use the crossposting feature to publish a video on multiple pages without uploading the video to each page. Refer to our detailed guidance on crossposting.
Example request
curl -X POST "https://rupload.facebook.com/video-upload/v25.0/video_id" \
-H "file_url: https://some.cdn.url/video.mp4"Upload a local file
To upload a local file, send a POST request to the upload_url endpoint you received in the initialization step with the following parameters:
offsetset to0file_sizeset to the total size in bytes of the video being uploaded
Example request
curl -X POST "https://rupload.facebook.com/video-upload/v25.0/video_id" \
-H "offset: 0" \
-H "file_size: file_size_in_bytes" \
--data-binary "@/path/to/file/my_video_file.mp4"On upload success, your app receives a JSON response with success set to true.
Example upload response
{
"success": true
}Interrupted upload
If the video upload is interrupted, you can either restart the upload or resume it.
- To restart the upload, resend the
POSTrequest and setoffsetto0. - To resume the upload, resend the
POSTrequest withoffsetset to thebytes_transferedvalue from a status check.
Get the upload status
To check a status of your video, during upload or publishing, send a GET request to the /video_id endpoint with the following parameter:
fieldsset tostatus
Example request
curl -X GET "https://graph.facebook.com/v25.0/video_id" \
-d "fields=status"On success, your app receives a JSON response that contains:
- A
statusobject that contains:video_statuswith a value ofready,processing,expired, orerroruploading_phaseobject with the following key-value pairs:statusset toin_progress,not_started,complete, orerrorbytes_transferedset to the bytes that have been uploaded. can be used as the value foroffsetif the upload is interrupted.
processing_phaseobject with the following key-value pairs:statusset toin_progress,not_started,complete, orerror
processing_phaseobject with the following key-value pairs:statusset toin_progress,not_started,complete, orerrorpublish_statusset topublishedornot_publishedpublish_timeset to a UNIX timestamp of the actual or published time
Example response
The following response shows a file that has been successfully uploaded.
{
"status": {
"video_status": "processing",
"uploading_phase": {
"status": "in_progress",
"bytes_transfered": 50002
},
"processing_phase": {
"status": "not_started"
}
"publishing_phase": {
"status": "not_started",
"publish_status": "published",
"publish_time": 234523452
}
}
}The following response shows an error has occurred in the processing phase.
{
"status": {
"video_status": "processing",
"uploading_phase": {
"status": "complete"
},
"processing_phase": {
"status": "not_started",
"error": {
"message": "Resolution too low. Video must have a minimum resolution of 540p."
}
}
"publishing_phase": {
"status": "not_started"
}
}
}Step 3. Publish a video story
To publish your video story to your Page, you will send a POST to the /page_id/video_stories endpoint with the following parameters:
video_idset to the ID for your uploaded videoupload_phaseset tofinish
Example request
curl -X POST "https://graph.facebook.com/v25.0/page_id/video_stories" \
-d '{
"video_id": "video_id",
"upload_phase": "finish"
}'On success, your app receives a JSON response that contains the following key-value pairs:
successset totruepost_idset to the ID for your story post
Example response
{
"success": true,
"post_id": 1234
}Photo stories
Step 1. Upload a photo
Visit the Page Posts Reference to learn how to upload a photo to Meta servers using the /page_id/photos endpoint. Be sure to include the published parameter and set it to false.
Step 2. Publish a photo story
To publish your photo story to your Page, you will send a POST to the /page_id/photo_stories endpoint with the following parameters:
photo_idset to the ID for your uploaded photo
Example request
curl -X POST "https://graph.facebook.com/v25.0/page_id/photo_stories" \
-d '{
"photo_id": "photo_id"
}'On success, your app receives a JSON response that contains the following key-value pairs:
successset totruepost_idset to the ID for your story post
Example response
{
"success": true,
"post_id": 1234
}Get stories
To get a list of all stories for a Page and data about each story, send a GET request to the /page_id/stories endpoint where page_id is the ID for the Page you want to view.
Example request
curl -i -X GET "https://graph.facebook.com/v25.0/page_id/stories"On success, your app receives a JSON response with an array of objects where each object contains information about a story published on the Page. Each object contains the following key-value pairs:
- The
post_idset to the ID for the published story post - The
statusset toPUBLISHED,ARCHIVED - The
creation_timeset to UNIX timestamp when the story was published - The
media_typeset to eithervideoorphoto - The
media_idset to the ID for the video or photo in the story post - The
urlset to the Facebook URL for the story post, such ashttps://facebook.com/stories/8283482737484972
Example Response
{
"data": [
{
"post_id": "post_id",
"status": "PUBLISHED",
"creation_time": "123456",
"media_type": "video",
"media_id": "video_id",
"url": "https://facebook.com/stories…"
},
{
"post_id": "post_id",
"status": "PUBLISHED",
"creation_time": "123456",
"media_type": "photo",
"media_id": "photo_id",
"url": "https://facebook.com/stories…"
},
{
"post_id": "post_id",
"status": "ARCHIVED",
"creation_time": "123456",
"media_type": "photo",
"media_id": "photo_id",
"url": "https://facebook.com/stories…"
},
...
],
}You can filter stories by status, published or archived, and date, using the since and until parameters.
See also
Learn more about the endpoints and concepts discussed in this guide.
Relevant guides
- Business system user
- Facebook Login
- Facebook Login for Business
- Graph API – Paginated Results with since and until