Reels Publishing API

This document explains how to publish a reel on a Facebook Page. To publish a reel on a Facebook Page, you will:

  1. Initialize an upload session to upload your reel to the Meta servers
  2. Upload your reel
  3. Publish the reel to your Facebook Page
  • Optionally, you can invite a collaborator to publish the reel on their Facebook Page.

Sharing Disclosure

When uploading a reel using your app, the app user should be presented with disclosure of and options for control over how their Reels are used on Facebook.

Privacy / Who can see this?

An app user should be able to select the audience for their reel. This selection corresponds to the privacy parameter in the publishing step. Publishing to a Page has implicit public scope, and only the 'Public' option should be available.

Limitations

  • You can only publish Reels to Facebook Pages
  • You can only crosspost Reels to Facebook Pages

Rate Limit

Reels API is limited to 30 API-published posts within a 24-hour moving period. This limit is enforced on the POST /{page_id}/video_reels endpoint when attempting to publish a reel. Meta recommends that your app also enforces the publishing rate limit, especially if your app allows app users to schedule posts to be published in the future.

Sharing Disclosure Mockup

Before You Start

You will need:

  • A Page access token requested from your app user who can perform the CREATE_CONTENT task on the Page
  • The your app user must grant your app the following permissions using Facebook Login:
    • pages_show_list
    • pages_read_engagement
    • pages_manage_posts
  • A video file that contains your reel

Video Specifications

PropertySpecification

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

Step 1: Initialize an Upload Session

Before you can publish a video to a Facebook Page, you must first upload it to the Meta social graph. You will need to initialize a video upload session to start the upload process. To start a session, send a POST request to the /page-id/video_reels endpoint, where page-id is the ID for your Facebook Page, with the upload_phase parameter set to start.

Be sure the host is graph.facebook.com.

Example Request

Formatted for readability. Replace bold, italics values, such as page_access_token, with your values.

curl -X POST "https://graph.facebook.com/v19.0/Your_page_id/video_reels" \
     -H "Content-Type: application/json" \
     -d '{
           "upload_phase":"start",
           "access_token":"Your_page_access_token"
         }'

On success, your app will receive a video ID and a URL to the video. This video ID will be used in subsequent steps.

{
  "video_id": "video-id",
  "upload_url": "https://rupload.facebook.com/video-upload/video-id",
}   

Step 2: Upload the Video

Most Graph API calls use the graph.facebook.com host however, calls to upload videos for reels use rupload.facebook.com.

The following file sources are supported for uploaded video files:

  • A file located on your computer
  • A file hosted on a public facing server, such as a CDN

Upload a Local File

To initiate the upload of the video asset, send a POST request using application/octet-stream as content type to the /video-upload/video-id endpoint where video-id is the ID from Step 1, offset is set to the first byte being upload, generally 0, and file_size set to the size of your file, in bytes.

Be sure the host is rupload.facebook.com.

Video Reel Upload Quick Reference

Example Request

Formatted for readability. Replace bold, italics values, such as page_access_token, with your values.

curl -X POST "https://rupload.facebook.com/video-upload/v19.0/video-id" \
     -H "Authorization: OAuth Your_page_access_token" \
     -H "offset: 0" \
     -H "file_size: Your_file_size_in_bytes" \
     --data-binary "@my_video_file.mp4"

Upload a Hosted File

To upload a hosted file, send a POST request to the /video-upload/video-id endpoint where video-id is the ID returned in Step 1 and file_url is set to the URL for your hosted file.

Be sure the host is rupload.facebook.com.

Example Request

Formatted for readability. Replace bold, italics values, such as page_access_token, with your values.

curl -X POST "https://rupload.facebook.com/video-upload/v19.0/video_id" \
     -H "Authorization: OAuth Your_page_access_token" \
     -H "file_url: https://some.cdn.url/video.mp4"

Example Upload Response

If you upload was successful, your app will receive a JSON object with success set to true.

{"success": true}

Get the Upload Status

To get the status of a video, send a GET request to the / video-id endpoint where the video-id is the ID from initialization step, and with fields set to status.

Be sure the host is graph.facebook.com.

Sample Request

curl -X GET "https://graph.facebook.com/v19.0/video-id
    ?fields=status
    &access_token=Your_page_access_token"

On success your app will receive a JSON object with status information that includes the processing, uploading, and publishing phases, and the video status.

Video Status Quick Reference

If re-uploading doesn’t work, try again from Step 1.

Example Response with a Processing Error
{
  "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",
    }
  }
}
Example Response for an Interrupted Upload
{
  "status": {
    "video_status": "processing", 
    "uploading_phase": {
      "status": "in_progress",
      "bytes_transfered": 50002  
    }
    "processing_phase": {
      "status": "not_started"
    }
    "publishing_phase": {
      "status": "not_started",
    }
  }
}
Error TypeError MessageRecommended Solution

OffsetInvalidError

Request starting offset is invalid

Set the ‘offset’ parameter to the bytes_transfered value returned in the Video endpoint status field

PartialRequestError

Partial request (did not match length of file)

Check the file size and try the upload again.

ProcessingFailedError

Request processing failed

Please try uploading again. Make sure the video meets all of the requirements. If the upload does not work, initialize a new upload session.

Resume an Interrupted Upload

If the video upload is interrupted, it can be resumed.

To resume an upload, send another POST request to the /video-upload/video-id endpoint and use the value for upload_phase.bytes_transfered as the value for offset.

Step 3: Publish the Reel

To end the upload session and publish your video, send a POSTrequest to the /page-id/video_reels endpoint. You can also include any of the additional fields, like description, which can include hashtags, and title.

Be sure the host is graph.facebook.com.

POST Page Video Reels Quick Reference

Example Request

Formatted for readability. Replace bold, italics values, such as page_access_token, with your values.

curl -X POST "https://graph.facebook.com/v19.0/page-id/video_reels
    ?access_token=Your_page_access_token
    &video_id=video-id
    &upload_phase=finish
    &video_state=PUBLISHED
    &description=What a beautiful day! #sunnyand72"

On success your app will receive a JSON object with success set to true.

{"success": true}

Get a List of Reels

To get a list of all reels published on your Facebook Page, send a GET request to /page-id/video_reels endpoint.

Be sure the host is graph.facebook.com for this API call.

Note: When using since and until in your GET request, the date for until must be a date after the date for since. For example, if since is 2023-01-31, until must be after 2023-01-31. You can use both parameters, or one or the other. Date formats can be any of the following:

  • today, yesterday
  • Epoch timestamps (1676057525)
  • yyyy-mm-dd (2023-1-31)
curl -X GET "https://graph.facebook.com/v19.0/page-id/video_reels?access_token=Your_page_access_token"

On success your app will receive a JSON object with information about your published reels such as video ID and published time.

{
  "data": [
    {
      "updated_time": "unix_timestamp",
      "id": "video-1-id"
    },
    {
      "description": "sample_description",
      "updated_time": "unix_timestamp",
      "id": "video-2-id"
    },
    ...
  ]
}

Invite a collaborator

Invite a person, a collaborator, to publish your reel on their Facebook Page.

To publish a reel on a collaborator's Facebook Page you will invite the collaborator to publish your reel on their Facebook Page. When they accept the invitation, the reel will immediately be published on their Facebook Page if the reel has been published, or the reel will be published on their Page when you publish the reel on your Page.

You will need:

  • The ID for the collaborator's Facebook Page (for New Page Experience, use the delegate Page ID)
  • The ID for the Video you want to share with a collaborator

Limitations

  • You can only send 10 collaborator invitation per Page per 24 hours
  • You can only publish Reels to other Facebook Pages

Send an Invitation

To invite a collaborator to publish your reel on their Facebook Page, send a POST request to the /video-id/collaborators endpoint with the target_id parameter set to the ID for the collaborator's Facebook Page.

Formatted for readability.
curl -X POST "https://graph.facebook.com/v19.0/video-id/collaborators
  ?target_id=collaborators-page-id 
  &access_token=your-page-access-token"

On success your app will receive a JSON response with the link to the invitation and your collaborator will receive an invite notification.

Example Response

{
  "success": true,
  “collaborator_id”: “collaborators-page-id”
  “invitation_link”: “facebook-url-for-invitation”
}

Get Invitation Status

To get the status for an invitation you sent, send a GET request to the /video-id/collaborators endpoint.

Example Request

Formatted for readability.
curl -X POST "https://graph.facebook.com/v19.0/video-id/collaborators
  ?access_token=your-page-or-user--access-token"

On success your app will receive a JSON response with the invitation status of Accepted, Declined, or Pending.

{
  “id”: “video-id”
  “name”: “collaborators-page-name”
  “invite_status”: “Accepted”
  “invitation_link”: “facebook-url-for-invitation”
}

Tag a location

To find a place to tag, you can use the Pages Search API. When searching for a place, only pages with valid locations can be used. When searching be sure to include the location field to verify this.

To tag the location in your reel, include the parameter place and the id returned from the Pages Search API in the publish call.

Example Request

curl -X POST "https://graph.facebook.com/v18.0/page-id/video_reels
    ?access_token=Your_page_access_token
    &video_id=video-id
    &upload_phase=finish
    &video_state=PUBLISHED
    &place=123456"

Retrieve Copyright Information

At upload, a copyright check is run to see if your upload contains licensed content and lets you act appropriately before publishing. Videos in violation may have restricted access or be subject to monetization impacts. To retrieve the copyright check information on the Reel, you must have pages_read_engagement permission on the Page. You will need the ID of the Video and the Page access token. Please note that it may take a couple of minutes for the copyright check to be completed and return information.

Limitations

  • Works for Reels API uploads

  • Only the owner can view the matches information

Example

Example Request

curl -i -X GET "https://graph.facebook.com/v18.0/VIDEO_ID?fields=copyright_check_information&access_token=ACCESS_TOKEN"

Example Responses

In progress:

{
  "copyright_check_information": {
        "status": {
            "status": "in_progress",
        },
    }
}

Without any matches:

{
  "copyright_check_information": {
        "status": {
            "status": "complete",
            "matches_found": false
        },
    }
}

With matches:

"copyright_check_information": {
        "status": {
            "status": "complete",
            "matches_found": true
        },
        "copyright_matches": [
            {
                "content_title": "Title 1",
                "owner_copyright_policy": {
                    "name": "Owner name 1",
                    "actions": [
                        {
                            "action": "TRACK",
                            "territories": "3",
                            "geos": [
                                "United Arab Emirates",
                                "Afghanistan",
                                "Antigua and Barbuda",
                            ]
                        }
                    ]
                },
                "matched_segments": [
                    {
                        "start_time_in_seconds": 90.5,
                        "duration_in_seconds": 35,
                        "segment_type": "AUDIO"
                    }
                ]
            },
            {
                "content_title": "Title 2",
                "owner_copyright_policy": {
                    "name": "Owner name 2",
                    "actions": [
                        {
                            "action": "BLOCK",
                            "territories": "1",
                            "geos": [
                                "Italy"
                            ]
                        }
                    ]
                },
                "matched_segments": [
                    {
                        "start_time_in_seconds": 90.5,
                        "duration_in_seconds": 35,
                        "segment_type": "AUDIO"
                    }
                ]
            }
        ]
    },

Error Codes

Common error codes and possible mitigations.

Error CodeError MessagePossible Mitigation

100

"error": { "message": "(#100) Missing parameter: {a list of missing parameters}", "type": "OAuthException", "code": 100, "fbtrace_id": "----" } }

A required parameter, such as upload_phase, is missing from your API call. Visit the endpoint reference to ensure all required parameters are included and be sure to check for typos.

1363040

The video you tried to upload has an aspect ratio that isn't supported on Facebook. Aspect ratios for videos need to be between 16x9 and 9x16. Please try uploading a video in a supported aspect ratio.

Aspect ratios for videos need to be between 16x9 and 9x16.

1363127

The video you tried to upload has resolution that isn't supported on Facebook for this product. Please try uploading a video with a supported resolution

Minimum resolution is 540 x 960 pixels. Recommended resolution is 1080 x 1920 pixels.

1363128

The video you tried to upload has a duration that isn't supported on Facebook for this product. Please try uploading a video with a supported duration.

Reels duration must be between 3 and 90 seconds.

1363129

The video you tried to upload has an average frame rate that isn't supported on Facebook for this product. Please try uploading a video with a supported frame rate

Reels frame rate must be between 24 and 60 frames per second.