Vector Assets API

Important

The Images API replaces the Assets API for uploading images and the Videos API replaces the Assets API for uploading videos. To understand more about the differences between Assets API vs Video API vs Images API, refer to compare & contrast section.

The assets API allows you to upload videos and images to the 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.
w_compliance Manage and delete data on behalf of an authenticated member for compliance requirements. This is a private permission and access is granted to select developers.

Note

All API requests 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. Currently, only jpeg and png formats are supported.

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
Background image for Dynamic Ads urn:li:digitalmediaRecipe:rightRail-logo-image
Sponsored Message Attachment urn:li:digitalmediaRecipe:ads-image

Note

Note that Sponsored Message Attachment content previously used the urn:li:digitalmediaRecipe:ads-messaging-attachment-image recipe which required strict permissions to access and was not preview-able. To address these constraints, the urn:li:digitalmediaRecipe:ads-image recipe has been repurposed to support this use case. It is less restrictive and is now preview-able.

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. owner URN The URN of the entity that owns this asset. Can be a Person(urn:li:person:123), Ad Account(urn:li:sponsoredAdAccount:123), or Organization(urn:li:organization:123) URN. For marketing use cases, this should be an Ad Account or Organization URN.
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.
  • CLIENT_ERROR Vector stops processing this artifact because the source file uploaded by the client is incorrect, for example, the file size is too large or the file format is unsupported by the vector asset.
  • SERVER_ERROR Vector service error, for example, a performance issue, database error, or network failure.
  • MUTATING Vector is reprocessing the asset and the asset is still available to be served. But the representation of the asset will be changed after reprocessing. Users should decide whether to take actions on this status.
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.
  • "SCHEDULED_DELETION": The asset has been scheduled for deletion. Possible reason: a user deleted their account.

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 output to upload your image.

The assets API supports the following image pixel count and formats:

  • Images with less than 36152320 pixels
  • JPG, GIF, and PNG formats
  • GIF format supports up to 250 frames

Upload Synchronously

It is required that image upload completes successfully before creating a UGC Post or Share. If the post is created before confirming image upload success and the image upload fails to process, the post will not be visible to members.

Therefore, we recommend that you use synchronous mode to upload images with the assets API instead of using the default asynchronous mode for this task. This is done by specifying SYNCHRONOUS_UPLOAD in the supportedUploadMechanism field. See the sample request below for an example.

Synchronous uploading provides a guaranteed response for the assets API after processing the image. This type of upload ensures your post will always be created and rendered correctly for your users.

If you opt to use asynchronous upload, it's crucial you confirm the upload succeeded before using the asset in a UGC Post or Share. Use the Check Status of Upload endpoint to validate success.

Sample Request

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

POST https://api.linkedin.com/rest/assets?action=registerUpload
{
   "registerUploadRequest":{
      "owner":"urn:li:organization:24141830",
      "recipes":[
         "urn:li:digitalmediaRecipe:feedshare-image"
      ],
      "serviceRelationships":[
         {
            "identifier":"urn:li:userGeneratedContent",
            "relationshipType":"OWNER"
         }
      ],
      "supportedUploadMechanism":[
         "SYNCHRONOUS_UPLOAD"
      ]
   }
}
POST https://api.linkedin.com/v2/assets?action=registerUpload
{
   "registerUploadRequest":{
      "owner":"urn:li:organization:24141830",
      "recipes":[
         "urn:li:digitalmediaRecipe:feedshare-image"
      ],
      "serviceRelationships":[
         {
            "identifier":"urn:li:userGeneratedContent",
            "relationshipType":"OWNER"
         }
      ],
      "supportedUploadMechanism":[
         "SYNCHRONOUS_UPLOAD"
      ]
   }
}

Sample Response

{
    "value": {
        "mediaArtifact": "urn:li:digitalmediaMediaArtifact:(urn:li:digitalmediaAsset:C5622AQHdBDflPp0pEg,urn:li:digitalmediaMediaArtifactClass:feedshare-uploadedImage)",
        "uploadMechanism": {
            "com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest": {
                "uploadUrl": "https://www.linkedin.com/dms-uploads/C5622AQHdBDflPp0pEg/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&sync=1&v=beta&ut=1lrKqjt4fYuqw1",
                "headers": {
                    "media-type-family": "STILLIMAGE"
                }
            }
        },
        "asset": "urn:li:digitalmediaAsset:C5622AQHdBDflPp0pEg",
        "assetRealTimeTopic": "urn:li-realtime:digitalmediaAssetUpdatesTopic:urn:li:digitalmediaAsset:C5622AQHdBDflPp0pEg"
    }
}

Upload the Image

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

The upload call requires a valid OAuth token in the 'Authorization' header. This is different than the upload video call which does not accept an OAuth token.

Sample curl Request

curl -i --upload-file ~/Desktop/Myimage.jpg -H 'Authorization: Bearer Redacted' "https://www.linkedin.com/dms-uploads/C5622AQHdBDflPp0pEg/feedshare-uploadedImage/0?ca=vector_feedshare&cn=uploads&sync=1&v=beta&ut=1lrKqjt4fYuqw1"

Sample Response

HTTP/2 201 
server: Play
set-cookie: lang=v=2&lang=en-us; Path=/; Domain=api.linkedin.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. Split the file into 5 MB each (split -b 5242880).
  3. Upload the video
  4. Complete multi-part upload
  5. Check status of upload

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

Schema

Field Name Type Description
registerUploadRequest. owner URN The URN of the entity that owns this asset. Can be a Person(urn:li:person:123), Ad Account(urn:li:sponsoredAdAccount:123), or Organization(urn:li:organization:123) URN. For marketing use cases, this should be an Ad Account or Organization URN.
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:ads-video (Deprecated)
  • urn:li:digitalmediaRecipe:ads-video_v2
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 The artifact is not available because it has been deleted or is in deleting process.
  • WAITING_UPLOAD Vector is waiting for client to upload source file or uploading process to be completed.
  • CLIENT_ERROR Vector stops processing this artifact because the source file uploaded by the client is incorrect, for example, the file size is too large or the file format is unsupported by the vector asset.
  • SERVER_ERROR Vector service error, for example, a performance issue, database error, or network failure.
  • MUTATING Vector is reprocessing the asset and the asset is still available to be served. But the representation of the asset will be changed after reprocessing. Users should decide whether to take actions on this status.
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.
  • "SCHEDULED_DELETION": The asset has been scheduled for deletion. Possible reason: a user deleted their account.

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 returned URL to upload the video. Redo this step if the upload fails.

Sample Request

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

POST https://api.linkedin.com/rest/assets?action=registerUpload
{
    "registerUploadRequest": {
        "owner": "urn:li:organization:24141830",
        "recipes": [
            "urn:li:digitalmediaRecipe:feedshare-video"
        ],
        "serviceRelationships": [
            {
                "identifier": "urn:li:userGeneratedContent",
                "relationshipType": "OWNER"
            }
        ]
    }
}
POST https://api.linkedin.com/v2/assets?action=registerUpload
{
    "registerUploadRequest": {
        "owner": "urn:li:organization:24141830",
        "recipes": [
            "urn:li:digitalmediaRecipe:feedshare-video"
        ],
        "serviceRelationships": [
            {
                "identifier": "urn:li:userGeneratedContent",
                "relationshipType": "OWNER"
            }
        ]
    }
}

Sample Response

{
    "value": {
        "mediaArtifact": "urn:li:digitalmediaMediaArtifact:(urn:li:digitalmediaAsset:C5605AQHAq1EzmbDx4A,urn:li:digitalmediaMediaArtifactClass:uploadedVideo)",
        "uploadMechanism": {
            "com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest": {
                "uploadUrl": "https://www.linkedin.com/dms-uploads/C5605AQHAq1EzmbDx4A/uploadedVideo/0?ca=vector_feedshare&cn=uploads_secure&ccn=ambry-video&sync=0&v=beta&ut=2IxLQWAqk1uGw1",
                "headers": {
                    "media-type-family": "VIDEO"
                }
            }
        },
        "asset": "urn:li:digitalmediaAsset:C5605AQHAq1EzmbDx4A",
        "assetRealTimeTopic": "urn:li-realtime:digitalmediaAssetUpdatesTopic:urn:li:digitalmediaAsset:C5605AQHAq1EzmbDx4A"
    }
}

The headers x-amz-server-side-encryption and x-amz-server-side-encryption-aws-kms-key-id can be ignored. These were required for past implementations, but are only present now for backwards compatibility.

Registering Multi-Part Upload

For videos larger than 200MB, split the file and register a MULTIPART_UPLOAD instead.

Sample Request

POST https://api.linkedin.com/rest/assets?action=registerUpload
{ 
   "registerUploadRequest":{ 
      "owner":"urn:li:organization:24141830",
      "recipes":[ 
         "urn:li:digitalmediaRecipe:feedshare-video"
      ],
      "serviceRelationships":[ 
         { 
            "identifier":"urn:li:userGeneratedContent",
            "relationshipType":"OWNER"
         }
      ],
      "supportedUploadMechanism":[ 
         "MULTIPART_UPLOAD"
      ],
      "fileSize": 52428801
   }
}
POST https://api.linkedin.com/v2/assets?action=registerUpload
{ 
   "registerUploadRequest":{ 
      "owner":"urn:li:organization:24141830",
      "recipes":[ 
         "urn:li:digitalmediaRecipe:feedshare-video"
      ],
      "serviceRelationships":[ 
         { 
            "identifier":"urn:li:userGeneratedContent",
            "relationshipType":"OWNER"
         }
      ],
      "supportedUploadMechanism":[ 
         "MULTIPART_UPLOAD"
      ],
      "fileSize": 52428801
   }
}

Sample Response

The metadata field in this response will be used again in order to complete the multi-part upload.

{
    "value": {
        "uploadMechanism": {
            "com.linkedin.digitalmedia.uploading.MultipartUpload": {
                "partUploadRequests": [
                    {
                        "headers": {
                            "Content-Type": "application/octet-stream"
                        },
                        "byteRange": {
                            "lastByte": 4194303,
                            "firstByte": 0
                        },
                        "url": "https://www.linkedin.com/dms-uploads/C4E05AQEw_VQIt69CrA/uploadedVideo?sau=aHR0cHM6Ly93d3cubGlua2VkaW4uY29tL2FtYnJ5L2FtYnJ5LXZpZGVvLz94LWxpLWFtYnJ5LWVwPUFRR0kzaFZtYmV2VXl3QUFBWFJhR0t1NlpNOVZnaUtCR0dfY0xhOUR5SUVacXE3UEVDZGtFWDlUSFJFU1lOcElnaDF1SzVRZVdmT0l3ZW5RSGl6V0UyUXBLYUNmZmRydG4yRUgyQ0lpSDRBXzAzLXRNRGQtOGZ3aFFLZTVBblJOTnVvTi15b0EySFZwTVJ0ZHRGd3hKRkVteTZIRTEyVXNjRnNPV3IySjJRMXZWTl9BcW1faDdWQVFEQVBqeFFpQVVVVUxOblFpNTJtc1JKUmtPMGZOcnBuelNZVVF6WFFncUZyYkFkOHdVaUwzS2h1Q2dDUEUxc2owMFR3MEk3TGlCbk9hbDlieEJFS0FhMFZJVzdwQlVxcFBlWUxXV0ZhZTlUUWhFVllHMkFYWFVsUjdERWp5b0lWT0tJcTlqZGUxb3hTYzZVdDBHSUxsWmUxOVhqbFc1dHJwdDM0YXh2VVhwYi1WX2h1LW9NTmJHUkVHN0RLYS1teWw3VWE5LVBWTUEwdUxKTUhleXlHVkxyTk9LbjM4UENVRkJCeUVTNzVoa0xUdV9LYUdNSjJ3QjQ4YnV2bzJqcGpkdjhSRmxubTloN3JtX1NkRFdJcUR6cHdZYnFiMV9ZNjVIdG03OC01eDhyb1VLSHhyMThNaTJRYTdvMktjZHdOLVE1WnJ4RWd1S0s4Ny1RYzRrcE9fdDhYY1VfeEZvYnNlUUxqTmpMNWpkSTd3czdIRUZKYmtlSFN0c0VwOVV6amdzYUdLRFpoWlMtWmw3amR0QWtqSjBvQkRIS0RGamlFSG0wYXBLNlFzY2N3UV95UU15SmVodFQwTTN2OE5pU1M1MmIya2dYd3hwUFFLU3RLQ05qMXNvaUxKZFZPanJQcTdzaWEyWWpyWnlWSXpUU0JHRFdtaGpSNTk0THZyekU5WnR3a2c0S0F5b3BiQnBna3NxR2lSeVFDcEU3Z2lGZmo5bjlRRnhFREVnendyU3FOVDNPaWo1NjhOSEVzVEN5WlAtLTFpS2V0MFpuRmdxNGxubTliMWdiT2NKai1FNlF2Q3otckJRMGpjT3ZUd21mSGxMVmlxQkFMUktfcHZEUkItZEpxMTJWTDd5UzdVbEUzSFVHYnpSRnRuV0VtQ0ZvUjI2Tzlqb1JvTzJpTnJ1LUEzYlM5cFRETXdRR3luMTl6R0VtYkxUZ3k0Mm0tRWE4NXR2ZERTbWp0MDRYMVZtazYwVEszRVpsRGNGVHNid0twTTdqRFcxNG45VF9PT3B5MUItYlJnekdGLXNEVXZiYTlPcWd5MzZvSlFkUnhiWGRrSS1JMDlKUWtWQUhqOUhwcVlhbklDLVFyek1JQ3QyczloZWR6cS1YUUcybDVvcnpyMERHQkh2SkdVVHRTb3NiaXF6X3NsM05RZ3AwaS1Kc3MzQzNZLVd3&pn=1&m=73633761&app=56349154&sync=0&v=beta&ut=1LEOuYNiICJpo1",
                        "urlExpiresAt": 1599325800381
                    },
                    {
                        "headers": {
                            "Content-Type": "application/octet-stream"
                        },
                        "byteRange": {
                            "lastByte": 8388607,
                            "firstByte": 4194304
                        },
                        "url": "https://www.linkedin.com/dms-uploads/C4E05AQEw_VQIt69CrA/uploadedVideo?sau=aHR0cHM6Ly93d3cubGlua2VkaW4uY29tL2FtYnJ5L2FtYnJ5LXZpZGVvLz94LWxpLWFtYnJ5LWVwPUFRR0kzaFZtYmV2VXl3QUFBWFJhR0t1NlpNOVZnaUtCR0dfY0xhOUR5SUVacXE3UEVDZGtFWDlUSFJFU1lOcElnaDF1SzVRZVdmT0l3ZW5RSGl6V0UyUXBLYUNmZmRydG4yRUgyQ0lpSDRBXzAzLXRNRGQtOGZ3aFFLZTVBblJOTnVvTi15b0EySFZwTVJ0ZHRGd3hKRkVteTZIRTEyVXNjRnNPV3IySjJRMXZWTl9BcW1faDdWQVFEQVBqeFFpQVVVVUxOblFpNTJtc1JKUmtPMGZOcnBuelNZVVF6WFFncUZyYkFkOHdVaUwzS2h1Q2dDUEUxc2owMFR3MEk3TGlCbk9hbDlieEJFS0FhMFZJVzdwQlVxcFBlWUxXV0ZhZTlUUWhFVllHMkFYWFVsUjdERWp5b0lWT0tJcTlqZGUxb3hTYzZVdDBHSUxsWmUxOVhqbFc1dHJwdDM0YXh2VVhwYi1WX2h1LW9NTmJHUkVHN0RLYS1teWw3VWE5LVBWTUEwdUxKTUhleXlHVkxyTk9LbjM4UENVRkJCeUVTNzVoa0xUdV9LYUdNSjJ3QjQ4YnV2bzJqcGpkdjhSRmxubTloN3JtX1NkRFdJcUR6cHdZYnFiMV9ZNjVIdG03OC01eDhyb1VLSHhyMThNaTJRYTdvMktjZHdOLVE1WnJ4RWd1S0s4Ny1RYzRrcE9fdDhYY1VfeEZvYnNlUUxqTmpMNWpkSTd3czdIRUZKYmtlSFN0c0VwOVV6amdzYUdLRFpoWlMtWmw3amR0QWtqSjBvQkRIS0RGamlFSG0wYXBLNlFzY2N3UV95UU15SmVodFQwTTN2OE5pU1M1MmIya2dYd3hwUFFLU3RLQ05qMXNvaUxKZFZPanJQcTdzaWEyWWpyWnlWSXpUU0JHRFdtaGpSNTk0THZyekU5WnR3a2c0S0F5b3BiQnBna3NxR2lSeVFDcEU3Z2lGZmo5bjlRRnhFREVnendyU3FOVDNPaWo1NjhOSEVzVEN5WlAtLTFpS2V0MFpuRmdxNGxubTliMWdiT2NKai1FNlF2Q3otckJRMGpjT3ZUd21mSGxMVmlxQkFMUktfcHZEUkItZEpxMTJWTDd5UzdVbEUzSFVHYnpSRnRuV0VtQ0ZvUjI2Tzlqb1JvTzJpTnJ1LUEzYlM5cFRETXdRR3luMTl6R0VtYkxUZ3k0Mm0tRWE4NXR2ZERTbWp0MDRYMVZtazYwVEszRVpsRGNGVHNid0twTTdqRFcxNG45VF9PT3B5MUItYlJnekdGLXNEVXZiYTlPcWd5MzZvSlFkUnhiWGRrSS1JMDlKUWtWQUhqOUhwcVlhbklDLVFyek1JQ3QyczloZWR6cS1YUUcybDVvcnpyMERHQkh2SkdVVHRTb3NiaXF6X3NsM05RZ3AwaS1Kc3MzQzNZLVd3&pn=2&m=73633761&app=56349154&sync=0&v=beta&ut=04tcszy7ICJpo1",
                        "urlExpiresAt": 1599325800381
                    },
                    ... // Additional upload URLS redacted
                ],
                "metadata": "eyJidWNrZXROYW1lIjoidmlkZW8tdXBsb2Fkcy1laSIsImtleU5hbWUiOiJDNTUwMEFRSEduM1pOa01OT0NRL2F3cy11c2VyVXBsb2FkZWRWaWRlbyIsInVwbG9hZElkIjoicDB0djRSdE1ORThGN19haklGY21EN0lSeGNZNlhzTmp5ZlZCaE1qQ18yWjUxOUlaOHhOZm1vaFFFcGNPY0xSM1VXb080cWlnRFQ0YmNkcExJMnhwZTgwa09aYzVZeHVDTzUxdS5FVTVwVVA5cjhsRUFpUm1ZMEdYNmhDQUk1ODEiLCJhc3NldElkIjoiQzU1MDBBUUhHbjNaTmtNTk9DUSIsIm1lZGlhQXJ0aWZhY3RJZCI6ImF3cy11c2VyVXBsb2FkZWRWaWRlbyJ9"
            }
        },
        "asset": "urn:li:digitalmediaAsset:C4E05AQEw_VQIt69CrA",
        "mediaArtifact": "urn:li:digitalmediaMediaArtifact:(urn:li:digitalmediaAsset:C4E05AQEw_VQIt69CrA,urn:li:digitalmediaMediaArtifactClass:uploadedVideo)"
    }
}

Upload the Video

Use the upload URL from the previous step to upload the video. Use a PUT method to upload the video.

The upload call should not include an OAuth token in the 'Authorization' header. This is different than the upload image call which requires an OAuth token.

Sample curl Request

curl -v -H "Content-Type:application/octet-stream" --upload-file /Users/username/SampleVideo_2mb.mp4 'https://www.linkedin.com/dms-uploads/C5400AQHpR1ANqMWqNA/uploadedVideo/0?ca=vector_feedshare&cn=uploads_secure&ccn=ambry-video&m=AQLEZ2pjh43pagYYYXRaCyztOykwDzluHkkYTbsMjNUzivrEOeObw9h3&app=1234&sync=1&v=beta&ut=1KeEm4JnMnJpo1'

The headers in the response will return an ETag if it is part of a multi-part upload.

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>, 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

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

The metadata field is passed to you in the response when registering a multi-part Upload. Use it again as shown in the sample below to complete the multi-part upload.

POST https://api.linkedin.com/rest/assets?action=completeMultiPartUpload
{
    "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
            }
        ]
    }
}
POST https://api.linkedin.com/v2/assets?action=completeMultiPartUpload
{
    "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. Wait for the upload to complete.

Sample Request

GET https://api.linkedin.com/rest/assets/C5400AQHpR1ANqMWqNA
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"
}

Compare & Contrast

Features Assets API Videos API Images API
Image Upload Mechanism For images, /assets API supports Synchronous upload, by default it is Asynchronous. NA /images API does not support Synchronous Upload.
Video Upload Mechanism File Size based upload - Only MULTIPART_UPLOAD for files greater than 200 MB and either SINGLE_REQUEST_UPLOAD or MULTIPART_UPLOAD otherwise. Unified protocol irrespective of the file size. the API will respond with upload URLs. If the response contains multiple upload urls, then videos have to be uploaded as multipart using the received link in the same order. NA
Video Upload Flow Complete Multipart upload action is used to complete the video upload with the help of Etags. In videos API, FinalizeUpload action is used to complete the video upload. NA
Video Supplementary Assets API does not support uploading of thumbnails and captions for videos. /videos API supports uploading of captions and thumbnails. The captions, thumbnails can be uploaded independent of the file size with multipart upload functionality by default. NA
Asset Reuse Developer needs to have understanding about concepts like recipes(either video or image). Assets generally cannot be reused. Videos API does not have any difference in terms of recipes and uploaded videos can be used across multiple video post formats. Eg. a video uploaded can be used for both organic posts and sponsored content ads. No need for recipes. Uploaded image can be used in multiple ad formats such as single Image Ads, Carousel Ads and Spotlight Ads.
API Responsibility /assets API is same for video and images making the schema generic and more complex.Output Urn- After an asset is uploaded, the urn is of type urn:li:digitalmediaAsset:C55FS. /videos is used for all video uploads (no need to pre-determine purpose).Output Urn- After a video is uploaded, the urn is of type urn:li:video:C5505 /images is used for all images uploads (no need to pre-determine purpose).Output Urn- After an image is uploaded, the urn is of type urn:li:image:C5505.
Asset Usage Uploaded Assets can be used from /videos and /images. Developer can take out the Id part from the Urn to use in the /videos API for the older videos uploaded using /assets API.For instance- /assets returns- urn:li:digitalmediaAsset:C5522AQHn46pwH96hxQ.To make use of the id in /videos API, simply reuse the id as urn:li:video:C5522AQHn46pwH96hxQ. Developer can take out the Id part from the Urn to use in the /images API for the older images uploaded using /assets API. For instance- /assets returns- urn:li:digitalmediaAsset:C5522AQHn46pwH96hxQ. To make use of the id in /images API, simply reuse the id as urn:li:image:C5522AQHn46pwH96hxQ.
Future Roadmap /assets API will not have any feature additions and will be deprecated in the future. /videos API will be improved with new features and is meant for long term availability. /images API will be improved with new features and is meant for long term availability.