Common Uses

Starting a Live Video

On a User

To start a live video stream on a User profile, get a User access token with the publish_video permission and send a POST request to the /{user-id}/live_videos edge and include the status=LIVE_NOW parameter. You can use the title and description parameters to include a title and description.

Upon success, this endpoint will return a stream_url, secure_stream_url, and a LiveVideo object id. The live video will appear in a post on the User's profile as soon as you send data to one of its stream URLs. You can use the live video ID to monitor your stream health, to end the stream, and to delete the video.

Sample Request

curl -i -X POST \
 "https://graph.facebook.com/{user-id}/live_videos
   ?status=LIVE_NOW
   &title=Today%27s%20Live%20Video
   &description=This%20is%20the%20live%20video%20for%20today.
   &access_token={access-token}"
GraphRequest request = GraphRequest.newPostRequest(
  accessToken,
  "/{user-id}/live_videos",
  new JSONObject("{\"title\":\"Today's Live Video\",\"description\":\"This is the live video for today.\"}"),
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});
request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/{user-id}/live_videos"
           parameters:@{ @"status": @"LIVE_NOW",@"title": @""Today's Live Video"",@"description": @""This is the live video for today."",}
           HTTPMethod:@"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/{user-id}/live_videos',
  'POST',
  {"status":"LIVE_NOW","title":"\"Today's Live Video\"","description":"\"This is the live video for today.\""},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->post(
    '/{user-id}/live_videos',
    array (
      'status' => 'LIVE_NOW',
      'title' => '"Today\'s Live Video"',
      'description' => '"This is the live video for today."'
    ),
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

Sample Response

{
  "id": "1953020644813104",
  "stream_url": "rtmp://rtmp-api.facebook...",
  "secure_stream_url":"rtmps://rtmp-api.facebook..."
}

On a Page

To start a live video stream on a Page, get a Page access token of an admin of the Page with the publish_video and manage_pages permissions. Then, send a POST request to the /{page-id}/live_videos edge and include the status=LIVE_NOW parameter. You can use the title and description parameters to include a title and description.

Upon success, this endpoint will return a stream_url, secure_stream_url, and a LiveVideo object id. The live video will appear in a post on the Page as soon as you send data to one of its stream URLs. You can use the live video ID to monitor your stream health, to end the stream, and to delete the video.

Sample Request

curl -i -X POST \
  "https://graph.facebook.com/{page-id}/live_videos
    ?status=LIVE_NOW
    &title=Today%27s%20Page%20Live%20Video
    &description=This%20is%20the%20live%20video%20for%20the%20Page%20for%20today
    &access_token=EAAC..."
GraphRequest request = GraphRequest.newPostRequest(
  accessToken,
  "/{page-id}/live_videos",
  new JSONObject("{\"title\":\"Today's Page Live Video\",\"description\":\"This is the live video for the Page for today.\"}"),
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});
request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/{page-id}/live_videos"
           parameters:@{ @"status": @"LIVE_NOW",@"title": @""Today's Page Live Video"",@"description": @""This is the live video for the Page for today."",}
           HTTPMethod:@"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/{page-id}/live_videos',
  'POST',
  {"status":"LIVE_NOW","title":"\"Today's Page Live Video\"","description":"\"This is the live video for the Page for today.\""},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->post(
    '/{page-id}/live_videos',
    array (
      'status' => 'LIVE_NOW',
      'title' => '"Today's Page Live Video"',
      'description' => '"This is the live video for the Page for today."'
    ),
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

Sample Response

{
  "id": "1953020644813108",
  "stream_url": "rtmp://rtmp-api.facebook...",
  "secure_stream_url":"rtmps://rtmp-api.facebook..."
}

On a Group

Before you can start a live video on a Group, the Group must install your app. A Group admin can do this on www.facebook.com by viewing the Group, going to Edit Group Settings > Apps > Add Apps, and adding your app.

To start a live video stream on a Group that has installed your app, get a User access token of an admin of the Group with the publish_video permission, then send a POST request to the /{group-id}/live_videos edge and include the status=LIVE_NOW parameter. You can use the title and description parameters to include a title and description.

Upon success, this endpoint will return a stream_url, secure_stream_url, and a LiveVideo object id. The live video will appear in a post on the Group as soon as you send data to one of its stream URLs. You can use the live video ID to monitor your stream health, to end the stream, and to delete the video.

Sample Request

curl -i -X POST \
  "https://graph.facebook.com/{group-id}/live_videos
    ?status=LIVE_NOW
    &title=Today%27s%20Group%20Live%20Video
    &description=This%20is%20the%20live%20video%20for%20the%20group%20for%20today
    &access_token=EAAC..."
GraphRequest request = GraphRequest.newPostRequest(
  accessToken,
  "/{group-id}/live_videos",
  new JSONObject("{\"title\":\"Today's Group Live Video\",\"description\":\"This is the live video for the Group for today.\"}"),
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});
request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/{group-id}/live_videos"
           parameters:@{ @"status": @"LIVE_NOW",@"title": @""Today's Group Live Video"",@"description": @""This is the live video for the Group for today."",}
           HTTPMethod:@"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/{group-id}/live_videos',
  'POST',
  {"status":"LIVE_NOW","title":"\"Today's Groups Live Video\"","description":"\"This is the live video for the Group for today.\""},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->post(
    '/{group-id}/live_videos',
    array (
      'status' => 'LIVE_NOW',
      'title' => '"Today's Group Live Video"',
      'description' => '"This is the live video for the Group for today."'
    ),
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

Sample Response

{
  "id": "1953020644813108",
  "stream_url": "rtmp://rtmp-api.facebook...",
  "secure_stream_url":"rtmps://rtmp-api.facebook..."
}

Getting Live Video Data

You can read live streams to get their preview URLs and data on streaming health, such as bitrates and framerates. Stream health data refreshes every 2 seconds, so limit queries to no more than once every 2 seconds. A stream timeout will be detected and reported after 4 seconds of no data being received.

To get live video data, get an appropriate User or Page access token with the publish_video permission, then send a GET request to the /{live-video-id} node and include the ingest_streams field.

Sample Request

curl -i -X GET \
  "https://graph.facebook.com/{live-video-id}
    ?fields=ingest_streams
    &access_token=EAAC..."
GraphRequest request = GraphRequest.newGraphPathRequest(
  accessToken,
  "/{live-video-id}",  
  new JSONObject("{\"fields\":\"ingest_streams\"}"),
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});

Bundle parameters = new Bundle();
parameters.putString("fields", "ingest_streams");
request.setParameters(parameters);
request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/{live-video-id}"     
           parameters:@{ @"fields": @"ingest_streams",}
           HTTPMethod:@"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/{live-video-id}',     
  'GET',
  {"fields":"ingest_streams"},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->get(
    '/{live-video-id}',      
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

Sample Response

{
  "ingest_streams": [
    {
      "stream_id": "0",
      "stream_url": "rtmp://rtmp-api.facebook...",
      "secure_stream_url": "rtmps://rtmp-api.facebook...",
      "is_master": true,
      "stream_health": {
        "video_bitrate": 4024116,
        "video_framerate": 60,
        "video_gop_size": 2000,
        "video_height": 720,
        "video_width": 1280,
        "audio_bitrate": 128745.4921875
      },
      "id": "1914910145231512"  // Ingest stream ID
    }
  ],
  "id": "{your-live-video-id}" 
}

Response Properties

Field NameDescription
audio_bitrate

Bits per second of the incoming audio stream.

is_master

true if the Live Video ID being queried is the video being delivered to an audience.

secure_stream_url

The secure RTMPS ingest URL for the Live Video ID being queried.

stream_url

The RTMP ingest URL for the Live Video ID being queried.

video_bitrate

Bits per second of the incoming video stream.

video_framerate

Frames per second of the incoming video stream.

video_gop_size

GOP (group of pictures) size in milliseconds.

video_height

Height in pixels of the incoming video frame.

video_width

Width in pixels of the incoming video frame.

Ending a Live Video

To end a live stream, send a POST request to the /{live-video-id} node and include the end_live_video=true parameter. This will set the LiveVideo object's status to VOD so that it can viewed on demand.

Upon success, the API will return the LiveVideo object's ID.

Sample Request

curl -i -X POST \
  "https://graph.facebook.com/{live-video-id}
    ?end_live_video=true
    &access_token=EAAC..."
GraphRequest request = GraphRequest.newPostRequest(
  accessToken,
  "/live-video-id",
  new JSONObject("{\"end_live_video\":\"true\"}\"),
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});
request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/{live-video-id}"
           parameters:@{ @"end_live_video": @"true",}
           HTTPMethod:@"POST"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/{live-video-id}',
  'POST',
  {"end_live_video":"true"},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->post(
    '/{live-video-id}',
    array (
      'end_live_video' => 'true'
    ),
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

Sample Response

{
  "id": "10213570560993813"
}

You can perform a GET operation on the live video's ID to confirm that its status has been set to VOD.

Sample Response

{
  "title": "\"Today's Live Video\"",
  "status": "VOD",  // Live video has ended and saved as a Video on Demand
  "stream_url": "rtmp://rtmp-api.facebook...",
  "secure_stream_url": "rtmps://rtmp-api.facebook...",
  "embed_html": "<iframe src=\"https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2Fuser.name%2Fvideos%2F10213570560993813%2F&width=0\" width=\"0\" height=\"0\" style=\"border:none;overflow:hidden\" scrolling=\"no\" frameborder=\"0\" allowTransparency=\"true\" allowFullScreen=\"true\"></iframe>",
  "id": "10213570560993813"
}

Deleting a Live Video

To delete a live video or VOD, send a DELETE request to the {live-video-id} node.

Sample Request

curl -i -X DELETE \
 "https://graph.facebook.com/{live-video-id}?access_token=EAAC..."
Bundle parameters = new Bundle();

GraphRequest request = new GraphRequest(
  accessToken,
  "/{live-video-id}",
  parameters,
  HttpMethod.DELETE,
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});

request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"{live-video-id}"
           parameters:nil
           HTTPMethod:@"DELETE"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/{live-video-id}',
  'DELETE',
  {},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->delete(
    '/{live-video-id}',
    array (),
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

Sample Response

{
  success: true
}

Getting Error Code Information

Error messages are sent via RTMP then to the Graph API. You can use the broadcast-id or live-video-id and query the error codes. Errors returned will contain the error code, type, message, and a timestamp.

Send a GET /id/ request where id is the live-video-id or the broadcast-id with the errors field.

Sample Response

curl -i -X GET \
 "https://graph.facebook.com/{your-live-video-id}
   ?fields=errors
   &access_token={your-access-token}"
GraphRequest request = GraphRequest.newGraphPathRequest(
  accessToken,
  "/1951440638245129",
  new GraphRequest.Callback() {
    @Override
    public void onCompleted(GraphResponse response) {
      // Insert your code here
    }
});

Bundle parameters = new Bundle();
parameters.putString("fields", "errors");
request.setParameters(parameters);
request.executeAsync();
FBSDKGraphRequest *request = [[FBSDKGraphRequest alloc]
    initWithGraphPath:@"/1951440638245129"
           parameters:@{ @"fields": @"errors",}
           HTTPMethod:@"GET"];
[request startWithCompletionHandler:^(FBSDKGraphRequestConnection *connection, id result, NSError *error) {
    // Insert your code here
}];
FB.api(
  '/1951440638245129',
  'GET',
  {"fields":"errors"},
  function(response) {
      // Insert your code here
  }
);
try {
  // Returns a `FacebookFacebookResponse` object
  $response = $fb->get(
    '/1951440638245129',
    '{access-token}'
  );
} catch(FacebookExceptionsFacebookResponseException $e) {
  echo 'Graph returned an error: ' . $e->getMessage();
  exit;
} catch(FacebookExceptionsFacebookSDKException $e) {
  echo 'Facebook SDK returned an error: ' . $e->getMessage();
  exit;
}
$graphNode = $response->getGraphNode();

Sample Response

{
  "errors": {
    "data": [
      {
        "error_code": 1969004,
        "error_type": "stream",
        "error_message": "Video signal lost",
        "creation_time": "2018-12-05T23:58:52+0000"
      },
      {
        "error_code": 1969004,
        "error_type": "stream",
        "error_message": "Video signal lost",
        "creation_time": "2018-12-05T23:58:52+0000"
      },
      {
        "error_code": 0,
        "error_type": "info",
        "error_message": "Live Service received the video signal",
        "creation_time": "2018-12-05T23:58:02+0000"
      },
      {
        "error_code": 0,
        "error_type": "info",
        "error_message": "Live Service received the video signal",
        "creation_time": "2018-12-05T23:58:02+0000"
      }
    ]
  },
  "id": "{your-live-video-id}"
}
error_subcodeError SummaryDescription
COPYRIGHT__LIVE_COPYRIGHT_VIOLATION

Live Copyright Violation

Your live video has been stopped because it may contain audio or visual content that belongs to a different Page.

VIDEO__CREATE_FAILED

Upload Problem

There was a problem and your video was not uploaded. Please try again.

LIVE_VIDEO__DELETE_FAILED

Live Video Not Deleted

There was a problem and we were not able to delete your live video. Please try again.

LIVE_VIDEO__EDIT_API_NOT_ALLOWED

Editing Via Video API Is Not Allowed While Live

Editing a live video using the Video Edit API is not allowed. Use the live video ID.

LIVE_VIDEO__LIVE_STREAM_ERROR

Generic Stream

There was an error during the stream

LIVE_VIDEO__NOT_EXIST

Live Video Does Not Exist

The live video you are trying to access does not exist in the system any more.

LIVE_VIDEO__PRIVACY_REQUIRED

Privacy Setting Required

You need to set a privacy before going live.