Glossar

Wie LinkedIn initializeUpload aus einer Datei eine Bild-URN macht

Taras Shynkarenko
Taras Shynkarenko
Aktualisiert: 8 Min. Lesezeit
Wie LinkedIn initializeUpload aus einer Datei eine Bild-URN machtWie LinkedIn initializeUpload aus einer Datei eine Bild-URN macht

TL;DR, Kurze Antwort

8 Min. Lesezeit

Ein Bild auf LinkedIn zu posten kostet drei Aufrufe. POST /rest/images?action=initializeUpload registriert den Upload und liefert eine uploadUrl, einen Zeitstempel uploadUrlExpiresAt und eine Bild-URN in der Form urn:li:image:{id}. Danach schickst du die Datei an diese URL, was die Assets-Seite als PUT mit OAuth-Token dokumentiert, und referenzierst die URN als content.media.id an POST /rest/posts. Jeder Schritt hat seine eigene Fehlertabelle, und LinkedIn dokumentiert für einen fehlgeschlagenen Upload keinen Wiederholungsweg außer von vorn anfangen.

Was macht der LinkedIn initializeUpload-Aufruf?

Ein LinkedIn initializeUpload-Aufruf registriert einen Bild-Upload, bevor ein einziges Byte fließt, und reicht die URL zurück, an die die Datei geht, plus die URN, die der Beitrag referenziert. LinkedIns eigene Beschreibung besteht aus drei Sätzen: „Use the initializeUpload action to register the upload. When you initialize, you declare the upcoming upload. Use the upload URL to upload the image."

Der Aufruf ist eine Aktion an der Images API, übergeben als Query-Parameter:

POST https://api.linkedin.com/rest/images?action=initializeUpload
Authorization: Bearer {INSERT_TOKEN}
Linkedin-Version: 202608
X-Restli-Protocol-Version: 2.0.0

{
  "initializeUploadRequest": {
    "owner": "urn:li:organization:5583111"
  }
}

Ein Pflichtfeld, initializeUploadRequest.owner, beschrieben als „URN of the entity that owns this asset. Can be a person(urn:li:person:123), or organization(urn:li:organization:123) URN." Das lohnt sich gegen das Bild-Schema selbst zu lesen, wo das Feld owner auf oberster Ebene auch eine sponsoredAccount-URN annimmt. Die Initialize-Anfrage führt nur Person und Organisation auf.

Das optionale zweite Feld registriert das Asset zugleich in der Medienbibliothek eines Werbekontos:

{
  "initializeUploadRequest": {
    "owner": "urn:li:organization:2414183",
    "mediaLibraryMetadata": {
      "associatedAccount": "urn:li:sponsoredAccount:123456789",
      "assetName": "My media library asset"
    }
  }
}

mediaLibraryMetadata.mediaLibraryStatus „defaults to ACTIVE on creation", ein Bibliotheks-Asset ist also live, sobald es fertig verarbeitet ist.

Eine Anmerkung stellt die Dokumentation in einen Kasten, weil sie ein Muster bricht, das viele aus der älteren Assets API mitbringen: „SYNCHRONOUS_UPLOAD is not supported in Images API." Es gibt keine Abkürzung in einem Aufruf. Die drei Schritte sind die ganze Oberfläche.

Was liefert initializeUpload zurück?

Eine 200 mit drei Werten, eingepackt in value:

{
   "value": {
       "uploadUrlExpiresAt": 1650567510704,
       "uploadUrl": "https://www.linkedin.com/dms-uploads/C4E10AQFoyyAjHPMQuQ/uploaded-image/0?ca=vector_ads&cn=uploads&sync=0&v=beta&ut=08zHQjMjAOLqc1",
       "image": "urn:li:image:C4E10AQFoyyAjHPMQuQ"
   }
}

Der Wert image ist die URN, und sie ist das Stück, das du speicherst. Alles Weitere verweist über diesen String auf das Bild: der Beitragskörper, der GET, der den Verarbeitungsstatus prüft, der Eintrag in der Medienbibliothek. Beachte, dass der Bezeichner in der URN derselbe ist wie der Bezeichner im Pfad der Upload-URL, was die beiden in Logs leicht zusammenbringt.

uploadUrlExpiresAt sind Millisekunden seit der Epoche. LinkedIn veröffentlicht nicht, wie lang das Fenster ist, also gehört der Zeitstempel gelesen statt eine Dauer angenommen. Eine Warteschlange, die einen Stapel Uploads Stunden vor dem Senden der Dateien initialisiert, verlässt sich auf eine Zahl, die niemand dokumentiert hat.

Auch die Form der Bild-URN lohnt eine Prüfung auf deiner Seite, denn die Images API weist fehlerhafte mit einem eigenen Fehler ab. urn:li:image: gefolgt vom Bezeichner, und nichts sonst. Die Images API nimmt „Images with less than 36,152,320 pixels" in „JPG, GIF, and PNG formats" an, wobei „GIF format supports up to 250 frames."

Ein Smartphone-Bildschirm zeigt einen laufenden Datei-Upload, den Schritt, in dem die Bilddaten an die URL aus initializeUpload gesendet werden.

Wie lädst du die Bilddaten hoch?

An die uploadUrl, mit der Datei als Body und demselben Bearer-Token. Die Assets-Seite, auf die die Images API für diesen Schritt verweist, ist bei der Methode eindeutig: „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 doesn't accept an OAuth token."

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"

Ein erfolgreicher Upload antwortet mit HTTP/2 201 und content-length: 0. Kein Body, kein JSON, nichts zu parsen. Das Einzige, was du erfährst, ist der Statuscode.

LinkedIn widerspricht sich beim Verb, und das ist gut zu wissen, bevor du eine 405 debuggst. Der Consumer-Leitfaden Share on LinkedIn, der den älteren /v2/assets-Flow behandelt, sagt, du sollst „send a POST request to the uploadUrl with your image or video included as a binary file", und demonstriert es dann mit curl -i --upload-file, was ein PUT ist. Die Assets-Seite sagt im Fließtext PUT und zeigt denselben Befehl. Der Befehl ist der verlässliche Teil beider Seiten.

Nach dem Upload liefert GET https://api.linkedin.com/rest/images/urn:li:image:C4E10AQFn10iWtKexVA das Asset mit einem Feld status. Die dokumentierten Werte sind WAITING_UPLOAD („Waiting for client to upload source file or uploading process to be completed"), PROCESSING, AVAILABLE („All of the recipe's required artifacts are ready. The asset is available to be served") und PROCESSING_FAILED, das das Schema auf „client error such as file size too large, unsupported file format, internal error" zurückführt.

AdaptlyPost
AdaptlyPost

7-Tage-Testversion starten

Plattformübergreifende Analysen

Sozialer Posteingang

KI-gestützter Assistent

Eine Berechtigungsfalle an diesem GET: Die Images API verlangt rw_ads, w_member_social, w_organization_social oder w_power_creators, und LinkedIn merkt an, dass „w_member_social permission are write-only and tokens with only w_member_social permissions would be unable to perform a GET call for rest/images." Eine auf ein Mitglied ausgelegte Integration kann hochladen und nicht abfragen.

Wie referenzierst du die Bild-URN in einem Beitrag?

Als content.media.id an der Posts API, neben dem Alt-Text:

POST https://api.linkedin.com/rest/posts

{
  "author": "urn:li:organization:5515715",
  "commentary": "test strings!",
  "visibility": "PUBLIC",
  "distribution": {
    "feedDistribution": "MAIN_FEED",
    "targetEntities": [],
    "thirdPartyDistributionChannels": []
  },
  "content": {
    "media": {
      "altText": "testing for alt tags",
      "id": "urn:li:image:C5610AQFj6TdYowm17w"
    }
  },
  "lifecycleState": "PUBLISHED",
  "isReshareDisabledByAuthor": false
}

„A successful response returns a 201 Created HTTP status code and the ID in the x-restli-id response header." Die URN des Beitrags kommt in einem Header zurück, nicht im Body, und sie sieht aus wie urn:li:share:6844785523593134080 oder urn:li:ugcPost:68447855235931240. Integrationen, die nur Antwort-Bodies lesen, verlieren die Beitrags-ID komplett.

Der altText an diesem Media-Objekt trägt seine eigene dokumentierte Decke, behandelt in der Aufschlüsselung dazu, wo LinkedIn sein Alt-Text-Limit hinschreibt. Für einen Beitrag mit mehreren Bildern wandern dieselben URNs stattdessen in ein images-Array, mit mindestens 2 und höchstens 20.

Eine Person liest eine Fehlermeldung auf einem Laptop-Bildschirm, ein Sinnbild für das Debugging nach einem fehlgeschlagenen Upload- oder Post-Aufruf.

Welche Fehler tauchen an welchem Schritt auf?

Drei Schritte, drei getrennte Fehlertabellen, und sie überschneiden sich nicht.

SchrittStatusCodeBedeutung
initializeUpload400INVALID_URN_TYPE„{field} value {value} must be a {urnType} URN"
initializeUpload400INVALID_URN_ID„This URN ID is invalid"
initializeUpload403keiner veröffentlicht„Accessing this image resource is forbidden. Please check your permissions for this resource"
initializeUpload400VERSION_MISSINGDer Version-Header fehlte an der Anfrage
Upload PUT401UNAUTHORIZED„The OAuth token is missing, invalid, or expired"
Upload PUT413REQUEST_ENTITY_TOO_LARGE„The uploaded file exceeds the allowed size limit"
Upload PUT415UNSUPPORTED_MEDIA_TYPE„The uploaded file format is not supported"
Upload PUT422UNPROCESSABLE_ENTITY„The server understands the request but can't process it"
POST /rest/posts400INVALID_URN_TYPE„Verify the URN type used for fields such as author or content.media.id"
POST /rest/posts400MISSING_FIELDauthor, visibility, distribution oder lifecycleState fehlt
POST /rest/posts403ACCESS_DENIEDScope erteilt, aber dem Mitglied fehlt die Rolle auf der Unternehmensseite
POST /rest/posts429TOO_MANY_REQUESTS„The API rate limit has been exceeded"

Die 403 beim Initialisieren gehört genau gelesen, weil LinkedIn sie als rohen Body statt als Code veröffentlicht und weil ihre Ursache meist eine Seitenrolle ist und kein Scope. Die dokumentierten Berechtigungsprüfungen sind rollenbasiert: „For images with company URN owners, the caller must have ADMIN or DSC permissions for the company page" und „For images with member URN owners, the caller must match the image owner."

Ein fehlender Version-Header lässt den Initialize-Aufruf scheitern, bevor irgendetwas davon geprüft wird, mit 400 VERSION_MISSING und der Meldung „A version must be present. Please specify a version by adding the Linkedin-Version header." Die Regeln zu diesem Header, samt dem, was ein abgeschalteter Wert liefert, liest man am besten neben diesem Ablauf im Beitrag zu dem Version-Header, den jeder /rest/-Aufruf braucht.

Was lässt LinkedIn hier undokumentiert?

Drei Dinge, und jedes davon ist eine Entscheidung, die du ohne Quelle treffen musst.

Wie lange die Upload-URL hält. Du bekommst uploadUrlExpiresAt in der Antwort und nirgends auf der Seite eine genannte Dauer, eine Planung, die Uploads bündelt, muss den Zeitstempel also als Vertrag behandeln.

Ob du auf AVAILABLE warten musst, bevor du den Beitrag erstellst. Die Statuswerte sind dokumentiert, der GET, der sie liefert, ist dokumentiert, und die Beziehung zwischen beiden und dem Aufruf POST /rest/posts ist es nicht. Das sichere Muster ist, bis AVAILABLE abzufragen, und es ist ein Muster und keine Regel.

Was bei PROCESSING_FAILED zu tun ist. Das Schema nennt die Ursachen und hört dort auf. Kein Endpunkt für einen erneuten Versuch ist dokumentiert, was in der Praxis heißt, einen neuen Upload zu initialisieren und eine neue URN zu bekommen. Teams, die das in Menge über einen LinkedIn-Post-Planer fahren, bauen diesen Wiederholungsweg am Ende selbst, so wie sie es für andere Publishing-APIs mit dreistufigen Medienabläufen tun.

Drei undokumentierte Entscheidungen
1
Gültigkeitsdauer der Upload-URL. Es gibt keine veröffentlichte Dauer, also gilt uploadUrlExpiresAt als einzige Garantie.
2
Warten auf AVAILABLE. Bis zum Statuswechsel zu pollen ist ein Muster, keine dokumentierte Regel.
3
PROCESSING_FAILED. Es gibt keinen Retry-Endpunkt, also besteht die Lösung aus einem neuen initializeUpload-Aufruf und einer neuen URN.
Jede dieser drei Entscheidungen triffst du ohne Beleg aus LinkedIns Dokumentation.

Häufig gestellte Fragen

Was ist der LinkedIn initializeUpload-Endpunkt?

POST https://api.linkedin.com/rest/images?action=initializeUpload. Es ist eine Aktion an der Images API, die einen Upload registriert und eine uploadUrl, einen Zeitstempel uploadUrlExpiresAt und eine image-URN liefert, bevor irgendwelche Dateidaten gesendet werden.

Wie sieht die Bild-URN aus initializeUpload aus?

urn:li:image:{id}, zum Beispiel urn:li:image:C4E10AQFoyyAjHPMQuQ. Derselbe Bezeichner steht im Pfad der zurückgelieferten Upload-URL, und die URN ist das, was du beim Erstellen des Beitrags als content.media.id übergibst.

Welche HTTP-Methode lädt das Bild zu LinkedIn hoch?

PUT. Die Assets-Seite hält fest „Use a PUT method to upload the image" und verlangt „a valid OAuth token in the 'Authorization' header", und ein erfolgreicher Upload liefert 201 mit leerem Body. Der Fließtext des Consumer-Leitfadens sagt POST, aber sein eigenes curl-Beispiel nutzt --upload-file, was ein PUT sendet.

AdaptlyPost
AdaptlyPost

7-Tage-Testversion starten

Plattformübergreifende Analysen

Sozialer Posteingang

KI-gestützter Assistent

Musst du warten, bis das Bild verarbeitet ist, bevor du postest?

LinkedIn dokumentiert keine verpflichtende Wartezeit. Dokumentiert ist ein Feld status am Bild mit den Werten WAITING_UPLOAD, PROCESSING, AVAILABLE und PROCESSING_FAILED, und GET /rest/images/{urn} bis AVAILABLE abzufragen ist die sichere Lesart davon.

Warum liefert initializeUpload eine 403?

Der dokumentierte Body ist „Accessing this image resource is forbidden. Please check your permissions for this resource" mit "status": 403. Die Berechtigungsprüfungen sind rollenbasiert: Bei einer Unternehmens-URN als Eigentümer braucht der Aufrufer ADMIN- oder DSC-Rechte auf der Seite, bei einer Mitglieds-URN muss er mit dem Eigentümer übereinstimmen.

Kann ein Token mit nur w_member_social die Images API nutzen?

Für Schreibzugriffe ja. LinkedIn hält fest, dass „w_member_social permission are write-only and tokens with only w_member_social permissions would be unable to perform a GET call for rest/images", ein solches Token kann also initialisieren und hochladen, aber den Bildstatus am versionierten Endpunkt nicht abfragen.

Welche Bildformate und -größen akzeptiert die LinkedIn Images API?

Die Images API akzeptiert JPG-, GIF- und PNG-Dateien mit maximal 36.152.320 Pixeln. GIF-Dateien dürfen bis zu 250 Frames haben. Diese Grenzen gelten für jedes Bild im dreistufigen Ablauf, nicht nur für einen einzelnen Schritt.

Unterstützt die LinkedIn Images API einen synchronen Upload?

Sie tut es nicht. LinkedIn hält das in einem Hinweis fest: "SYNCHRONOUS_UPLOAD is not supported in Images API." Die drei Aufrufe, initializeUpload, der PUT und POST /rest/posts, sind die gesamte Oberfläche, es gibt keine Ein-Schritt-Abkürzung wie im Muster, das manche aus der älteren Assets API übernehmen.

Welche OAuth-Scopes erlauben den Zugriff auf die LinkedIn Images API?

rw_ads, w_member_social, w_organization_social oder w_power_creators. Jeder der vier deckt initializeUpload und den Upload-PUT ab, aber w_member_social allein kann den Bildstatus nicht per GET abrufen, da LinkedIn diesen Scope als reinen Schreibzugriff dokumentiert.

Wie viele Bilder kann ein LinkedIn-Post enthalten?

Ein Post mit einem Bild referenziert eine URN über content.media.id. Ein Post mit mehreren Bildern nutzt stattdessen ein images-Array, das laut LinkedIn mindestens 2 und höchstens 20 URNs enthalten muss.

War dieser Artikel hilfreich?

Teilen Sie uns Ihre Meinung mit!

Sieh uns öfter bei Google

Ein Klick macht AdaptlyPost zu einer bevorzugten Quelle. Unsere Artikel stehen dann weiter oben in deinen Top-Meldungen, im KI-Modus und in den KI-Übersichten.

Bevor Sie gehen...

AdaptlyPost

AdaptlyPost

Planen Sie Ihre Inhalte für alle Plattformen

Verwalten Sie alle Ihre Social-Media-Konten an einem Ort mit AdaptlyPost.

Plattformübergreifende Analysen

Sozialer Posteingang

KI-gestützter Assistent

Verwandte Glossarbegriffe

Verwandte Artikel