Assets API

The assets API allows you to upload videos and images to LinkedIn platform. These media uploads can then be referenced in a User-Generated Content (UGC) Post or various sponsored content and campaign Ads. Partners can create and upload rich and engaging personal or organization content to be surfaced on various feeds within the LinkedIn ecosystem.

Permissions

Permission Description
w_compliance Required to manage and delete data for compliance.
w_organization_social Post, comment and like posts on behalf of an organization. Restricted to organizations in which the authenticated member has one of the
w_member_social Post, comment and like posts on behalf of an authenticated member.
rw_ads Create ads and creatives for a sponsored account.

Note

All API requests are represented in protocol 2.0.0 and require the header X-Restli-Protocol-Version: 2.0.0.

How to Upload Images

Determine the recipe type of your image asset before uploading your image. Use the table below as a guideline to prepare your image with the appropriate recipe.

LinkedIn supports up to 33,177,600 pixels in a UGC Post.

Content Recipe
Shares or UGC Post on behalf of an organization or member urn:li:digitalmediaRecipe:feedshare-image
Image or Article Ad for a campaign urn:li:digitalmediaRecipe:companyUpdate-article-image
Carousel Ad for a campaign urn:li:digitalmediaRecipe:ssu-carousel-card-image
Text Ad for a campaign urn:li:digitalmediaRecipe:rightRail-logo-image
Dynamic Ads for a campaign urn:li:digitalmediaRecipe:rightRail-logo-image

Upload Image With Assets API:

  1. Register an upload for Image
  2. Upload the Image
  3. Check status of upload

Schema

Field Name Type Description
registerUploadRequest. recipes URN[] The recipe URN identifies the use case associated with the upload request. The URN can be any of the following types:
  • urn:li:digitalmediaRecipe:feedshare-image
  • urn:li:digitalmediaRecipe:companyUpdate-article-image
  • urn:li:digitalmediaRecipe:ssu-carousel-card-image
  • urn:li:digitalmediaRecipe:rightRail-logo-image
registerUploadRequest. recipes[*].status String read-only
  • NEW A newly assigned recipe. This status is only used for new assignments. Transitions to PROCESSING as soon as processing requests are sent.
  • PROCESSING Some or all of the recipe's required artifacts are not available and processing is underway to generate the missing artifacts.
  • AVAILABLE All of the recipe's required artifacts are available.
  • INCOMPLETE Some or all of the recipe's required artifacts are not available and no further processing is being done.
  • WAITING_UPLOAD Waiting for client to upload source file or uploading process to be completed.
registerUploadRequest. serviceRelationships[*]. relationshipType String Possible values are as follows:
  • GENERIC
  • CREATOR
  • OWNER
registerUploadRequest. serviceRelationships[*]. identifier String Should be of type - urn:li:userGeneratedContent
status String read-only
  • ALLOWED The content is allowed to be served.
  • BLOCKED The content must not be served.
  • ABANDONED The asset was abandoned by its owner. Some possible reasons: Upload was cancelled; The application no longer needs it; The uploaded file is not of the intended type.
  • DELETED The asset was fully deleted and cannot be processed again. Deletion might have been triggered by client.

Note

registerUploadRequest.serviceRelationships array size cannot be greater than 5.

Register an Upload for Images

Use the registerUpload action to register the image upload. Use the HTTP URL that's returned to upload the image. Use the uploadUrl returned within the response body to upload your image.

Sample Request

POST https://api.linkedin.com/v2/assets?action=registerUpload

Make sure you set the Content-Type header to application/json.

{
    "registerUploadRequest": {
        "owner": "urn:li:organization:10000",
        "recipes": [
            "urn:li:digitalmediaRecipe:feedshare-image"
        ],
        "serviceRelationships": [
            {
                "identifier": "urn:li:userGeneratedContent",
                "relationshipType": "OWNER"
            }
        ]
    }
}

Sample Response

{
    "value": {
        "uploadMechanism": {
            "com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest": {
                "headers": {
                    "media-type-family": "STILLIMAGE"
                },
                "uploadUrl": "https://api.linkedin.com/mediaUpload/C5522AQHn46pwH96hxQ/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQLKRJOn_yNw6wAAAW2T0DWnRStny4dzsNVJjlF3aN4-H3ZR9Div77kKoQ&app=1983914&sync=0&v=beta&ut=1Dnjy796bpjEY1"
            }
        },
        "mediaArtifact": "urn:li:digitalmediaMediaArtifact:(urn:li:digitalmediaAsset:C5522AQHn46pwH96hxQ,urn:li:digitalmediaMediaArtifactClass:feedshare-uploadedImage)",
        "asset": "urn:li:digitalmediaAsset:C5522AQHn46pwH96hxQ"
    }
}

Upload the Image

Use the uploadUrl from the previous step to upload the image. Use a PUT method to upload the image

Sample curl Request

curl -i --upload-file ~/Desktop/Myimage.jpg -H 'Authorization: Bearer Redacted' "https://api.linkedin.com/mediaUpload/C5522AQHn46pwH96hxQ/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&m=AQLKRJOn_yNw6wAAAW2T0DWnRStny4dzsNVJjlF3aN4-H3ZR9Div77kKoQ&app=1983914&sync=0&v=beta&ut=1Dnjy796bpjEY1"

Sample Response

HTTP/2 201 
server: Play
set-cookie: lang=v=2&lang=en-us; Path=/; Domain=api.linkedin-ei.com
date: Wed, 16 Oct 2019 06:25:12 GMT
content-length: 0
x-li-proto: http/2
report-to: {"group":"network-errors","max_age":2592000,"endpoints":[{"url":"https://www.linkedin.com/li/rep"}],"include_subdomains":true}
nel: {"report_to":"network-errors","max_age":1296000,"success_fraction":0.0001,"failure_fraction":1,"include_subdomains":true}
x-li-uuid: slguD4sMzhUwATrTkisAAA==
set-cookie: lidc="b=ETB86:g=301:u=12:i=1571207079:t=1571261189:s=AQGEngFr_Vc-bGAR4gREsIou-eLZon31"

How to upload Videos

Depending on the size of the video you are uploading, use one of the following options:

  • Upload videos in a single operation — Upload videos less than 200 MB in a single operation.
  • Upload videos in parts — Upload videos greater than 200 MB using multi-part upload.

To upload a video as a single asset:

  1. Register an upload for Video
  2. Upload the video
  3. Check status of upload

To upload a large video in multiple parts:

  1. Register an upload for Video
  2. Using the Media Upload metadata, split the file into 5 MB each (split -b 5242880).
  3. Upload the video
  4. Complete multi-part upload
  5. Check status of upload

If you are using legacy permissions, please refer to this page for requesting legacy permissions.

See Organization Access Control for more information on company page roles.

Schema

Field Name Type Description
registerUploadRequest. supportedUploadMechanism UploadMechanismType[], default="[ SINGLE_REQUEST_UPLOAD ]" Set it as SINGLE_REQUEST_UPLOAD if filesize < 200MB. For content greater than 200MB, set it as ["MULTIPART_UPLOAD"]
registerUploadRequest. fileSize Optional Long Size in bytes
registerUploadRequest. recipes URN[] The value is an URN that identifies the use case for which the upload is requested. It can be list of any of the following urns
  • urn:li:digitalmediaRecipe:feedshare-video
  • urn:li:digitalmediaRecipe:learning-image
  • urn:li:digitalmediaRecipe:ads-video
registerUploadRequest. recipes[*].status read-only String
  • NEW A newly assigned recipe. This status is only used for new assignments. Transitions to PROCESSING as soon as processing requests are sent.
  • PROCESSING Some or all of the recipe's required artifacts are not available and processing is underway to generate the missing artifacts.
  • AVAILABLE All of the recipe's required artifacts are available.
  • INCOMPLETE Some or all of the recipe's required artifacts are not available and no further processing is being done.
  • WAITING_UPLOAD Waiting for client to upload source file or uploading process to be completed.
registerUploadRequest. serviceRelationships[*]. relationshipType String Possible values are as follows:
  • GENERIC
  • CREATOR
  • OWNER
registerUploadRequest. serviceRelationships[*]. identifier String Should be of type - urn:li:userGeneratedContent
status String read-only
  • ALLOWED The content is allowed to be served.
  • BLOCKED The content must not be served.
  • ABANDONED The asset was abandoned by its owner. Some possible reasons: Upload was cancelled; The application no longer needs it; The uploaded file is not of the intended type; etc.
  • DELETED The asset was fully deleted and cannot be processed again. Deletion might have been triggered by client.

Note

registerUploadRequest.serviceRelationships array size cannot be greater than 5.

Register an Upload for Video

Use the registerUpload action to register the upload. When you register, you declare the upcoming upload. Use the HTTP URL that's returned to upload the video. Redo this step if the upload fails.

Sample Request

POST https://api.linkedin.com/v2/assets?action=registerUpload

Make sure you set the Content-Type header to application/json.

{
    "registerUploadRequest": {
        "owner": "urn:li:organization:10000",
        "recipes": [
            "urn:li:digitalmediaRecipe:feedshare-video"
        ],
        "serviceRelationships": [
            {
                "identifier": "urn:li:userGeneratedContent",
                "relationshipType": "OWNER"
            }
        ]
    }
}

Sample Response

{
    "value": {
        "asset": "urn:li:digitalmediaAsset:C5400AQHpR1ANqMWqNA",
        "mediaArtifact": "urn:li:digitalmediaMediaArtifact:(urn:li:digitalmediaAsset:C5400AQHpR1ANqMWqNA,urn:li:digitalmediaMediaArtifactClass:aws-userUploadedVideo)",
        "uploadMechanism": {
            "com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest": {
                "headers": {
                    "Content-Type": "application/octet-stream",
                    "x-amz-server-side-encryption": "aws:kms",
                    "x-amz-server-side-encryption-aws-kms-key-id": "e10ace24-blah-4977-bar-89foo193e2ab"
                },
                "uploadUrl": "https://video-uploads.s3-accelerate.amazonaws.com/C5400AQHpR1ANqMWqNA/aws-userUploadedVideo?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20180120T000018Z&X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-server-side-encryption%3Bx-amz-server-side-encryption-aws-kms-key-id&X-Amz-Expires=86400&X-Amz-Credential=AKIAJYU2MA%2F20180120%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=f7c0756a80998786766588878768778768977687d4c687b3f1a0e8"
            }
        }
    }
}

Registering Multi-Part Upload

POST https://api.linkedin.com/v2/assets?action=registerUpload

Sample Response

{ 
   "registerUploadRequest":{ 
      "owner":"urn:li:organization:10000",
      "recipes":[ 
         "urn:li:digitalmediaRecipe:feedshare-video"
      ],
      "serviceRelationships":[ 
         { 
            "identifier":"urn:li:userGeneratedContent",
            "relationshipType":"OWNER"
         }
      ],
      "supportedUploadMechanism":[ 
         "MULTIPART_UPLOAD"
      ],
      "fileSize": 52428801
   }
}

Upload the Video

Use the headers and uploadUrl from the previous step to upload the video. Use a PUT method to upload the video.

Sample curl Request

curl -v  -H "Content-Type:application/octet-stream"
-H "x-amz-server-side-encryption:aws:kms"
-H "x-amz-server-side-encryption-aws-kms-key-id:e10ace24-blah-4977-bar-89foo193e2ab"
--upload-file /Users/username/SampleVideo_2mb.mp4 'https://video-uploads.s3-accelerate.amazonaws.com/C5400AQHpR1ANqMWqNA/aws-userUploadedVideo?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20180120T000018Z&X-Amz-SignedHeaders=content-type%3Bhost%3Bx-amz-server-side-encryption%3Bx-amz-server-side-encryption-aws-kms-key-id&X-Amz-Expires=86400&X-Amz-Credential=AKIAJYU2MA%2F20180120%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=f7c0756a80998786766588878768778768977687d4c687b3f1a0e8'

The headers in the response returns an eTag.

HTTP/1.1 200 OK
Content-Length: 0
Connection: keep-alive
x-amz-id-2: 2wer1EizXFXQneT6n1VAa4l1ggPOM9cOl0jJFgpk0ocOYyZsjLKAHaQwmOKi47hHG6D9R2w4y5A=
x-amz-request-id: C6DA7DF813E33C69
Date: Thu, 27 Sep 2018 22:40:01 GMT
x-amz-version-id: AguPSmqVmxmrKvuJ56mIDeUu5FqnJffZ
x-amz-server-side-encryption: aws:kms
x-amz-server-side-encryption-aws-kms-key-id: arn:aws:kms:us-east-1:123456789:key/e10ace24-blah-4977-bar-89foo193e2ab
ETag: "e4383924336106965d6cd2a111beaceb"
Server: AmazonS3
X-Amz-Cf-Id: CgvELDhzYQgJ8qpJka_pAscHJ4Dnwsc0sDj4zZAiwnji-YZXK2aRdA==

Complete Multi-Part Upload

When you register a video as a multi-part upload by setting "supportedUploadMechanism":["MULTIPART_UPLOAD"] and registerUploadRequest.fileSize = <file size> in the previous step, you receive a response with multiple upload URLs and headers. Upload the split file using the URLs. See Upload the Video for an example. Once you upload the content, the response headers of each upload returns an eTag. Use the eTags to complete the multi-part upload.

Sample Request

POST https://api.linkedin.com/v2/assets?action=completeMultiPartUpload

Make sure to set the Content-Type header to application/json.

{
    "completeMultipartUploadRequest": {
        "mediaArtifact": "urn:li:digitalmediaMediaArtifact:(urn:li:digitalmediaAsset:C5500AQHGn3ZNkMNOCQ,urn:li:digitalmediaMediaArtifactClass:aws-userUploadedVideo)",
        "metadata": "eyJidWNrZXROYW1lIjoidmlkZW8tdXBsb2Fkcy1laSIsImtleU5hbWUiOiJDNTUwMEFRSEduM1pOa01OT0NRL2F3cy11c2VyVXBsb2FkZWRWaWRlbyIsInVwbG9hZElkIjoicDB0djRSdE1ORThGN19haklGY21EN0lSeGNZNlhzTmp5ZlZCaE1qQ18yWjUxOUlaOHhOZm1vaFFFcGNPY0xSM1VXb080cWlnRFQ0YmNkcExJMnhwZTgwa09aYzVZeHVDTzUxdS5FVTVwVVA5cjhsRUFpUm1ZMEdYNmhDQUk1ODEiLCJhc3NldElkIjoiQzU1MDBBUUhHbjNaTmtNTk9DUSIsIm1lZGlhQXJ0aWZhY3RJZCI6ImF3cy11c2VyVXBsb2FkZWRWaWRlbyJ9",
        "partUploadResponses": [
            {
                "headers": {
                    "ETag": "d8a5ce5adcdac4063feabcda7183396e"
                },
                "httpStatusCode": 200
            },
            {
                "headers": {
                    "ETag": "24259a14365734f1f1b4abcdb5e55d01e"
                },
                "httpStatusCode": 200
            }
        ]
    }
}

Check Status of Upload

You can retrieve asset information using the Asset ID from the digitalmediaAsset URN. Depending on content size, it might take a few minutes for the upload to complete.

Sample Request

GET https://api.linkedin.com/v2/assets/C5400AQHpR1ANqMWqNA

Sample Response

{
    "created": 1521582700662,
    "id": "C5405AQEOFHXqeM2vRA",
    "lastModified": 1521583180818,
    "mediaTypeFamily": "VIDEO",
    "recipes": [
        {
            "recipe": "urn:li:digitalmediaRecipe:feedshare-video",
            "status": "PROCESSING"
        }
    ],
    "serviceRelationships": [
        {
            "identifier": "urn:li:userGeneratedContent",
            "relationshipType": "OWNER"
        }
    ],
    "status": "ALLOWED"
}