{
  "schemaVersion": "1.0",
  "item": {
    "slug": "linkedin-api",
    "name": "LinkedIn",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/byungkyu/linkedin-api",
    "canonicalUrl": "https://clawhub.ai/byungkyu/linkedin-api",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/linkedin-api",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=linkedin-api",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "SKILL.md",
      "LICENSE.txt"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/linkedin-api"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/linkedin-api",
    "agentPageUrl": "https://openagent3.xyz/skills/linkedin-api/agent",
    "manifestUrl": "https://openagent3.xyz/skills/linkedin-api/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/linkedin-api/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "LinkedIn",
        "body": "Access the LinkedIn API with managed OAuth authentication. Share posts, manage advertising campaigns, retrieve profile and organization information, upload media, and access the Ad Library."
      },
      {
        "title": "Quick Start",
        "body": "# Get current user profile\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/linkedin/rest/me')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('LinkedIn-Version', '202506')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Base URL",
        "body": "https://gateway.maton.ai/linkedin/rest/{resource}\n\nThe gateway proxies requests to api.linkedin.com and automatically injects your OAuth token."
      },
      {
        "title": "Authentication",
        "body": "All requests require the Maton API key in the Authorization header:\n\nAuthorization: Bearer $MATON_API_KEY\n\nEnvironment Variable: Set your API key as MATON_API_KEY:\n\nexport MATON_API_KEY=\"YOUR_API_KEY\""
      },
      {
        "title": "Getting Your API Key",
        "body": "Sign in or create an account at maton.ai\nGo to maton.ai/settings\nCopy your API key"
      },
      {
        "title": "Required Headers",
        "body": "LinkedIn REST API requires the version header:\n\nLinkedIn-Version: 202506"
      },
      {
        "title": "Connection Management",
        "body": "Manage your LinkedIn OAuth connections at https://ctrl.maton.ai."
      },
      {
        "title": "List Connections",
        "body": "python <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections?app=linkedin&status=ACTIVE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Create Connection",
        "body": "python <<'EOF'\nimport urllib.request, os, json\ndata = json.dumps({'app': 'linkedin'}).encode()\nreq = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Get Connection",
        "body": "python <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nResponse:\n\n{\n  \"connection\": {\n    \"connection_id\": \"ba10eb9e-b590-4e95-8c2e-3901ff94642a\",\n    \"status\": \"ACTIVE\",\n    \"creation_time\": \"2026-02-07T08:00:24.372659Z\",\n    \"last_updated_time\": \"2026-02-07T08:05:16.609085Z\",\n    \"url\": \"https://connect.maton.ai/?session_token=...\",\n    \"app\": \"linkedin\",\n    \"metadata\": {}\n  }\n}\n\nOpen the returned url in a browser to complete OAuth authorization."
      },
      {
        "title": "Delete Connection",
        "body": "python <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Specifying Connection",
        "body": "If you have multiple LinkedIn connections, specify which one to use with the Maton-Connection header:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/linkedin/rest/me')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('LinkedIn-Version', '202506')\nreq.add_header('Maton-Connection', 'ba10eb9e-b590-4e95-8c2e-3901ff94642a')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nIf omitted, the gateway uses the default (oldest) active connection."
      },
      {
        "title": "Profile",
        "body": "Get Current User Profile\n\nGET /linkedin/rest/me\nLinkedIn-Version: 202506\n\nExample:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/linkedin/rest/me')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('LinkedIn-Version', '202506')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nResponse:\n\n{\n  \"firstName\": {\n    \"localized\": {\"en_US\": \"John\"},\n    \"preferredLocale\": {\"country\": \"US\", \"language\": \"en\"}\n  },\n  \"localizedFirstName\": \"John\",\n  \"lastName\": {\n    \"localized\": {\"en_US\": \"Doe\"},\n    \"preferredLocale\": {\"country\": \"US\", \"language\": \"en\"}\n  },\n  \"localizedLastName\": \"Doe\",\n  \"id\": \"yrZCpj2Z12\",\n  \"vanityName\": \"johndoe\",\n  \"localizedHeadline\": \"Software Engineer at Example Corp\",\n  \"profilePicture\": {\n    \"displayImage\": \"urn:li:digitalmediaAsset:C4D00AAAAbBCDEFGhiJ\"\n  }\n}"
      },
      {
        "title": "Sharing Posts",
        "body": "Create a Text Post\n\nPOST /linkedin/rest/posts\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"author\": \"urn:li:person:{personId}\",\n  \"lifecycleState\": \"PUBLISHED\",\n  \"visibility\": \"PUBLIC\",\n  \"commentary\": \"Hello LinkedIn! This is my first API post.\",\n  \"distribution\": {\n    \"feedDistribution\": \"MAIN_FEED\"\n  }\n}\n\nResponse: 201 Created with x-restli-id header containing the post URN.\n\nCreate an Article/URL Share\n\nPOST /linkedin/rest/posts\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"author\": \"urn:li:person:{personId}\",\n  \"lifecycleState\": \"PUBLISHED\",\n  \"visibility\": \"PUBLIC\",\n  \"commentary\": \"Check out this great article!\",\n  \"distribution\": {\n    \"feedDistribution\": \"MAIN_FEED\"\n  },\n  \"content\": {\n    \"article\": {\n      \"source\": \"https://example.com/article\",\n      \"title\": \"Article Title\",\n      \"description\": \"Article description here\"\n    }\n  }\n}\n\nCreate an Image Post\n\nFirst, initialize the image upload, then upload the image, then create the post.\n\nStep 1: Initialize Image Upload\n\nPOST /linkedin/rest/images?action=initializeUpload\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"initializeUploadRequest\": {\n    \"owner\": \"urn:li:person:{personId}\"\n  }\n}\n\nResponse:\n\n{\n  \"value\": {\n    \"uploadUrlExpiresAt\": 1770541529250,\n    \"uploadUrl\": \"https://www.linkedin.com/dms-uploads/...\",\n    \"image\": \"urn:li:image:D4D10AQH4GJAjaFCkHQ\"\n  }\n}\n\nStep 2: Upload Image Binary\n\nPUT {uploadUrl from step 1}\nContent-Type: image/png\n\n{binary image data}\n\nStep 3: Create Image Post\n\nPOST /linkedin/rest/posts\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"author\": \"urn:li:person:{personId}\",\n  \"lifecycleState\": \"PUBLISHED\",\n  \"visibility\": \"PUBLIC\",\n  \"commentary\": \"Check out this image!\",\n  \"distribution\": {\n    \"feedDistribution\": \"MAIN_FEED\"\n  },\n  \"content\": {\n    \"media\": {\n      \"id\": \"urn:li:image:D4D10AQH4GJAjaFCkHQ\",\n      \"title\": \"Image Title\"\n    }\n  }\n}"
      },
      {
        "title": "Visibility Options",
        "body": "ValueDescriptionPUBLICViewable by anyone on LinkedInCONNECTIONSViewable by 1st-degree connections only"
      },
      {
        "title": "Share Media Categories",
        "body": "ValueDescriptionNONEText-only postARTICLEURL/article shareIMAGEImage postVIDEOVideo post"
      },
      {
        "title": "Ad Library (Public Data)",
        "body": "The Ad Library API provides access to public advertising data on LinkedIn. These endpoints use the REST API with version headers.\n\nRequired Headers for Ad Library\n\nLinkedIn-Version: 202506\n\nSearch Ads\n\nGET /linkedin/rest/adLibrary?q=criteria&keyword={keyword}\n\nQuery parameters:\n\nkeyword (string): Search ad content (multiple keywords use AND logic)\nadvertiser (string): Search by advertiser name\ncountries (array): Filter by ISO 3166-1 alpha-2 country codes\ndateRange (object): Filter by served dates\nstart (integer): Pagination offset\ncount (integer): Results per page (max 25)\n\nExample - Search ads by keyword:\n\nGET /linkedin/rest/adLibrary?q=criteria&keyword=linkedin\n\nExample - Search ads by advertiser:\n\nGET /linkedin/rest/adLibrary?q=criteria&advertiser=microsoft\n\nResponse:\n\n{\n  \"paging\": {\n    \"start\": 0,\n    \"count\": 10,\n    \"total\": 11619543,\n    \"links\": [...]\n  },\n  \"elements\": [\n    {\n      \"adUrl\": \"https://www.linkedin.com/ad-library/detail/...\",\n      \"details\": {\n        \"advertiser\": {...},\n        \"adType\": \"TEXT_AD\",\n        \"targeting\": {...},\n        \"statistics\": {\n          \"firstImpressionDate\": 1704067200000,\n          \"latestImpressionDate\": 1706745600000,\n          \"impressionsFrom\": 1000,\n          \"impressionsTo\": 5000\n        }\n      },\n      \"isRestricted\": false\n    }\n  ]\n}\n\nSearch Job Postings\n\nGET /linkedin/rest/jobLibrary?q=criteria&keyword={keyword}\n\nNote: Job Library requires version 202506.\n\nQuery parameters:\n\nkeyword (string): Search job content\norganization (string): Filter by company name\ncountries (array): Filter by country codes\ndateRange (object): Filter by posting dates\nstart (integer): Pagination offset\ncount (integer): Results per page (max 24)\n\nExample:\n\nGET /linkedin/rest/jobLibrary?q=criteria&keyword=software&organization=google\n\nResponse includes:\n\njobPostingUrl: Link to job listing\njobDetails: Title, location, description, salary, benefits\nstatistics: Impression data"
      },
      {
        "title": "Marketing API (Advertising)",
        "body": "The Marketing API provides access to LinkedIn's advertising platform. These endpoints use the versioned REST API.\n\nRequired Headers for Marketing API\n\nLinkedIn-Version: 202506\n\nList Ad Accounts\n\nGET /linkedin/rest/adAccounts?q=search\n\nReturns all ad accounts accessible by the authenticated user.\n\nResponse:\n\n{\n  \"paging\": {\n    \"start\": 0,\n    \"count\": 10,\n    \"links\": []\n  },\n  \"elements\": [\n    {\n      \"id\": 123456789,\n      \"name\": \"My Ad Account\",\n      \"status\": \"ACTIVE\",\n      \"type\": \"BUSINESS\",\n      \"currency\": \"USD\",\n      \"reference\": \"urn:li:organization:12345\"\n    }\n  ]\n}\n\nGet Ad Account\n\nGET /linkedin/rest/adAccounts/{adAccountId}\n\nCreate Ad Account\n\nPOST /linkedin/rest/adAccounts\nContent-Type: application/json\n\n{\n  \"name\": \"New Ad Account\",\n  \"currency\": \"USD\",\n  \"reference\": \"urn:li:organization:{orgId}\",\n  \"type\": \"BUSINESS\"\n}\n\nUpdate Ad Account\n\nPOST /linkedin/rest/adAccounts/{adAccountId}\nContent-Type: application/json\nX-RestLi-Method: PARTIAL_UPDATE\n\n{\n  \"patch\": {\n    \"$set\": {\n      \"name\": \"Updated Account Name\"\n    }\n  }\n}\n\nList Campaign Groups\n\nCampaign groups are nested under ad accounts:\n\nGET /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups\n\nCreate Campaign Group\n\nPOST /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups\nContent-Type: application/json\n\n{\n  \"name\": \"Q1 2026 Campaigns\",\n  \"status\": \"DRAFT\",\n  \"runSchedule\": {\n    \"start\": 1704067200000,\n    \"end\": 1711929600000\n  },\n  \"totalBudget\": {\n    \"amount\": \"10000\",\n    \"currencyCode\": \"USD\"\n  }\n}\n\nGet Campaign Group\n\nGET /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups/{campaignGroupId}\n\nUpdate Campaign Group\n\nPOST /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups/{campaignGroupId}\nContent-Type: application/json\nX-RestLi-Method: PARTIAL_UPDATE\n\n{\n  \"patch\": {\n    \"$set\": {\n      \"status\": \"ACTIVE\"\n    }\n  }\n}\n\nDelete Campaign Group\n\nDELETE /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups/{campaignGroupId}\n\nList Campaigns\n\nCampaigns are also nested under ad accounts:\n\nGET /linkedin/rest/adAccounts/{adAccountId}/adCampaigns\n\nCreate Campaign\n\nPOST /linkedin/rest/adAccounts/{adAccountId}/adCampaigns\nContent-Type: application/json\n\n{\n  \"campaignGroup\": \"urn:li:sponsoredCampaignGroup:123456\",\n  \"name\": \"Brand Awareness Campaign\",\n  \"status\": \"DRAFT\",\n  \"type\": \"SPONSORED_UPDATES\",\n  \"objectiveType\": \"BRAND_AWARENESS\",\n  \"dailyBudget\": {\n    \"amount\": \"100\",\n    \"currencyCode\": \"USD\"\n  },\n  \"costType\": \"CPM\",\n  \"unitCost\": {\n    \"amount\": \"5\",\n    \"currencyCode\": \"USD\"\n  },\n  \"locale\": {\n    \"country\": \"US\",\n    \"language\": \"en\"\n  }\n}\n\nGet Campaign\n\nGET /linkedin/rest/adAccounts/{adAccountId}/adCampaigns/{campaignId}\n\nUpdate Campaign\n\nPOST /linkedin/rest/adAccounts/{adAccountId}/adCampaigns/{campaignId}\nContent-Type: application/json\nX-RestLi-Method: PARTIAL_UPDATE\n\n{\n  \"patch\": {\n    \"$set\": {\n      \"status\": \"ACTIVE\"\n    }\n  }\n}\n\nDelete Campaign\n\nDELETE /linkedin/rest/adAccounts/{adAccountId}/adCampaigns/{campaignId}"
      },
      {
        "title": "Campaign Status Values",
        "body": "StatusDescriptionDRAFTCampaign is in draft modeACTIVECampaign is runningPAUSEDCampaign is pausedARCHIVEDCampaign is archivedCOMPLETEDCampaign has endedCANCELEDCampaign was canceled"
      },
      {
        "title": "Campaign Objective Types",
        "body": "ObjectiveDescriptionBRAND_AWARENESSIncrease brand visibilityWEBSITE_VISITSDrive traffic to websiteENGAGEMENTIncrease post engagementVIDEO_VIEWSMaximize video viewsLEAD_GENERATIONCollect leads via Lead Gen FormsWEBSITE_CONVERSIONSDrive website conversionsJOB_APPLICANTSAttract job applications"
      },
      {
        "title": "Organizations",
        "body": "List Organization ACLs\n\nGet organizations the authenticated user has access to:\n\nGET /linkedin/rest/organizationAcls?q=roleAssignee\nLinkedIn-Version: 202506\n\nResponse:\n\n{\n  \"paging\": {\n    \"start\": 0,\n    \"count\": 10,\n    \"total\": 2\n  },\n  \"elements\": [\n    {\n      \"role\": \"ADMINISTRATOR\",\n      \"organization\": \"urn:li:organization:12345\",\n      \"state\": \"APPROVED\"\n    }\n  ]\n}\n\nGet Organization\n\nGET /linkedin/rest/organizations/{organizationId}\nLinkedIn-Version: 202506\n\nLookup Organization by Vanity Name\n\nGET /linkedin/rest/organizations?q=vanityName&vanityName={vanityName}\n\nExample:\n\nGET /linkedin/rest/organizations?q=vanityName&vanityName=microsoft\n\nResponse:\n\n{\n  \"elements\": [\n    {\n      \"vanityName\": \"microsoft\",\n      \"localizedName\": \"Microsoft\",\n      \"website\": {\n        \"localized\": {\"en_US\": \"https://news.microsoft.com/\"}\n      }\n    }\n  ]\n}\n\nGet Organization Share Statistics\n\nGET /linkedin/rest/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity={orgUrn}\n\nExample:\n\nGET /linkedin/rest/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:12345\n\nGet Organization Posts\n\nGET /linkedin/rest/posts?q=author&author={orgUrn}\n\nExample:\n\nGET /linkedin/rest/posts?q=author&author=urn:li:organization:12345"
      },
      {
        "title": "Media Upload (REST API)",
        "body": "The REST API provides modern media upload endpoints. All require version header LinkedIn-Version: 202506.\n\nInitialize Image Upload\n\nPOST /linkedin/rest/images?action=initializeUpload\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"initializeUploadRequest\": {\n    \"owner\": \"urn:li:person:{personId}\"\n  }\n}\n\nResponse:\n\n{\n  \"value\": {\n    \"uploadUrlExpiresAt\": 1770541529250,\n    \"uploadUrl\": \"https://www.linkedin.com/dms-uploads/...\",\n    \"image\": \"urn:li:image:D4D10AQH4GJAjaFCkHQ\"\n  }\n}\n\nUse the uploadUrl to PUT your image binary, then use the image URN in your post.\n\nInitialize Video Upload\n\nPOST /linkedin/rest/videos?action=initializeUpload\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"initializeUploadRequest\": {\n    \"owner\": \"urn:li:person:{personId}\",\n    \"fileSizeBytes\": 10000000,\n    \"uploadCaptions\": false,\n    \"uploadThumbnail\": false\n  }\n}\n\nResponse:\n\n{\n  \"value\": {\n    \"uploadUrlsExpireAt\": 1770541530110,\n    \"video\": \"urn:li:video:D4D10AQE_p-P_odQhXQ\",\n    \"uploadInstructions\": [\n      {\"uploadUrl\": \"https://www.linkedin.com/dms-uploads/...\"}\n    ]\n  }\n}\n\nInitialize Document Upload\n\nPOST /linkedin/rest/documents?action=initializeUpload\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"initializeUploadRequest\": {\n    \"owner\": \"urn:li:person:{personId}\"\n  }\n}\n\nResponse:\n\n{\n  \"value\": {\n    \"uploadUrlExpiresAt\": 1770541530896,\n    \"uploadUrl\": \"https://www.linkedin.com/dms-uploads/...\",\n    \"document\": \"urn:li:document:D4D10AQHr-e30QZCAjQ\"\n  }\n}"
      },
      {
        "title": "Ad Targeting",
        "body": "Get Available Targeting Facets\n\nGET /linkedin/rest/adTargetingFacets\n\nReturns all available targeting facets for ad campaigns (31 facets including employers, degrees, skills, locations, industries, etc.).\n\nResponse:\n\n{\n  \"elements\": [\n    {\n      \"facetName\": \"skills\",\n      \"adTargetingFacetUrn\": \"urn:li:adTargetingFacet:skills\",\n      \"entityTypes\": [\"SKILL\"],\n      \"availableEntityFinders\": [\"AD_TARGETING_FACET\", \"TYPEAHEAD\"]\n    },\n    {\n      \"facetName\": \"industries\",\n      \"adTargetingFacetUrn\": \"urn:li:adTargetingFacet:industries\"\n    }\n  ]\n}\n\nAvailable targeting facets include:\n\nskills - Member skills\nindustries - Industry categories\ntitles - Job titles\nseniorities - Seniority levels\ndegrees - Educational degrees\nschools - Educational institutions\nemployers / employersPast - Current/past employers\nlocations / geoLocations - Geographic targeting\ncompanySize - Company size ranges\ngenders - Gender targeting\nageRanges - Age range targeting"
      },
      {
        "title": "Getting Your Person ID",
        "body": "To create posts, you need your LinkedIn person ID. Get it from the /rest/me endpoint:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/linkedin/rest/me')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('LinkedIn-Version', '202506')\nresult = json.load(urllib.request.urlopen(req))\nprint(f\"Your person URN: urn:li:person:{result['id']}\")\nEOF"
      },
      {
        "title": "JavaScript - Create Text Post",
        "body": "const personId = 'YOUR_PERSON_ID';\n\nconst response = await fetch(\n  'https://gateway.maton.ai/linkedin/rest/posts',\n  {\n    method: 'POST',\n    headers: {\n      'Authorization': `Bearer ${process.env.MATON_API_KEY}`,\n      'Content-Type': 'application/json',\n      'LinkedIn-Version': '202506'\n    },\n    body: JSON.stringify({\n      author: `urn:li:person:${personId}`,\n      lifecycleState: 'PUBLISHED',\n      visibility: 'PUBLIC',\n      commentary: 'Hello from the API!',\n      distribution: {\n        feedDistribution: 'MAIN_FEED'\n      }\n    })\n  }\n);"
      },
      {
        "title": "Python - Create Text Post",
        "body": "import os\nimport requests\n\nperson_id = 'YOUR_PERSON_ID'\n\nresponse = requests.post(\n    'https://gateway.maton.ai/linkedin/rest/posts',\n    headers={\n        'Authorization': f'Bearer {os.environ[\"MATON_API_KEY\"]}',\n        'Content-Type': 'application/json',\n        'LinkedIn-Version': '202506'\n    },\n    json={\n        'author': f'urn:li:person:{person_id}',\n        'lifecycleState': 'PUBLISHED',\n        'visibility': 'PUBLIC',\n        'commentary': 'Hello from the API!',\n        'distribution': {\n            'feedDistribution': 'MAIN_FEED'\n        }\n    }\n)"
      },
      {
        "title": "Rate Limits",
        "body": "Throttle TypeDaily Limit (UTC)Member150 requests/dayApplication100,000 requests/day"
      },
      {
        "title": "Notes",
        "body": "Person IDs are unique per application and not transferable across apps\nThe author field must use URN format: urn:li:person:{personId}\nAll posts require lifecycleState: \"PUBLISHED\"\nImage/video uploads are a 3-step process: initialize upload, upload binary, create post\nInclude LinkedIn-Version: 202506 header for all REST API calls\nProfile picture URLs may expire; re-fetch if needed\nIMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing\nIMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments"
      },
      {
        "title": "Error Handling",
        "body": "StatusMeaning400Missing LinkedIn connection or invalid request401Invalid or missing Maton API key403Insufficient permissions (check OAuth scopes)404Resource not found422Invalid request body or URN format429Rate limited4xx/5xxPassthrough error from LinkedIn API"
      },
      {
        "title": "Error Response Format",
        "body": "{\n  \"status\": 403,\n  \"serviceErrorCode\": 100,\n  \"code\": \"ACCESS_DENIED\",\n  \"message\": \"Not enough permissions to access resource\"\n}"
      },
      {
        "title": "Troubleshooting: API Key Issues",
        "body": "Check that the MATON_API_KEY environment variable is set:\n\necho $MATON_API_KEY\n\nVerify the API key is valid by listing connections:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF"
      },
      {
        "title": "Troubleshooting: Invalid App Name",
        "body": "Ensure your URL path starts with linkedin. For example:\n\nCorrect: https://gateway.maton.ai/linkedin/rest/me\nIncorrect: https://gateway.maton.ai/rest/me"
      },
      {
        "title": "OAuth Scopes",
        "body": "ScopeDescriptionopenidOpenID Connect authenticationprofileRead basic profileemailRead email addressw_member_socialCreate, modify, and delete posts"
      },
      {
        "title": "Resources",
        "body": "LinkedIn API Overview\nShare on LinkedIn Guide\nProfile API\nSign In with LinkedIn\nAuthentication Guide\nMarketing API\nAd Accounts\nCampaign Management\nAd Library API\nMaton Community\nMaton Support"
      }
    ],
    "body": "LinkedIn\n\nAccess the LinkedIn API with managed OAuth authentication. Share posts, manage advertising campaigns, retrieve profile and organization information, upload media, and access the Ad Library.\n\nQuick Start\n# Get current user profile\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/linkedin/rest/me')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('LinkedIn-Version', '202506')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nBase URL\nhttps://gateway.maton.ai/linkedin/rest/{resource}\n\n\nThe gateway proxies requests to api.linkedin.com and automatically injects your OAuth token.\n\nAuthentication\n\nAll requests require the Maton API key in the Authorization header:\n\nAuthorization: Bearer $MATON_API_KEY\n\n\nEnvironment Variable: Set your API key as MATON_API_KEY:\n\nexport MATON_API_KEY=\"YOUR_API_KEY\"\n\nGetting Your API Key\nSign in or create an account at maton.ai\nGo to maton.ai/settings\nCopy your API key\nRequired Headers\n\nLinkedIn REST API requires the version header:\n\nLinkedIn-Version: 202506\n\nConnection Management\n\nManage your LinkedIn OAuth connections at https://ctrl.maton.ai.\n\nList Connections\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections?app=linkedin&status=ACTIVE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nCreate Connection\npython <<'EOF'\nimport urllib.request, os, json\ndata = json.dumps({'app': 'linkedin'}).encode()\nreq = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('Content-Type', 'application/json')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nGet Connection\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\n\nResponse:\n\n{\n  \"connection\": {\n    \"connection_id\": \"ba10eb9e-b590-4e95-8c2e-3901ff94642a\",\n    \"status\": \"ACTIVE\",\n    \"creation_time\": \"2026-02-07T08:00:24.372659Z\",\n    \"last_updated_time\": \"2026-02-07T08:05:16.609085Z\",\n    \"url\": \"https://connect.maton.ai/?session_token=...\",\n    \"app\": \"linkedin\",\n    \"metadata\": {}\n  }\n}\n\n\nOpen the returned url in a browser to complete OAuth authorization.\n\nDelete Connection\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nSpecifying Connection\n\nIf you have multiple LinkedIn connections, specify which one to use with the Maton-Connection header:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/linkedin/rest/me')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('LinkedIn-Version', '202506')\nreq.add_header('Maton-Connection', 'ba10eb9e-b590-4e95-8c2e-3901ff94642a')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\n\nIf omitted, the gateway uses the default (oldest) active connection.\n\nAPI Reference\nProfile\nGet Current User Profile\nGET /linkedin/rest/me\nLinkedIn-Version: 202506\n\n\nExample:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/linkedin/rest/me')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('LinkedIn-Version', '202506')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\n\nResponse:\n\n{\n  \"firstName\": {\n    \"localized\": {\"en_US\": \"John\"},\n    \"preferredLocale\": {\"country\": \"US\", \"language\": \"en\"}\n  },\n  \"localizedFirstName\": \"John\",\n  \"lastName\": {\n    \"localized\": {\"en_US\": \"Doe\"},\n    \"preferredLocale\": {\"country\": \"US\", \"language\": \"en\"}\n  },\n  \"localizedLastName\": \"Doe\",\n  \"id\": \"yrZCpj2Z12\",\n  \"vanityName\": \"johndoe\",\n  \"localizedHeadline\": \"Software Engineer at Example Corp\",\n  \"profilePicture\": {\n    \"displayImage\": \"urn:li:digitalmediaAsset:C4D00AAAAbBCDEFGhiJ\"\n  }\n}\n\nSharing Posts\nCreate a Text Post\nPOST /linkedin/rest/posts\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"author\": \"urn:li:person:{personId}\",\n  \"lifecycleState\": \"PUBLISHED\",\n  \"visibility\": \"PUBLIC\",\n  \"commentary\": \"Hello LinkedIn! This is my first API post.\",\n  \"distribution\": {\n    \"feedDistribution\": \"MAIN_FEED\"\n  }\n}\n\n\nResponse: 201 Created with x-restli-id header containing the post URN.\n\nCreate an Article/URL Share\nPOST /linkedin/rest/posts\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"author\": \"urn:li:person:{personId}\",\n  \"lifecycleState\": \"PUBLISHED\",\n  \"visibility\": \"PUBLIC\",\n  \"commentary\": \"Check out this great article!\",\n  \"distribution\": {\n    \"feedDistribution\": \"MAIN_FEED\"\n  },\n  \"content\": {\n    \"article\": {\n      \"source\": \"https://example.com/article\",\n      \"title\": \"Article Title\",\n      \"description\": \"Article description here\"\n    }\n  }\n}\n\nCreate an Image Post\n\nFirst, initialize the image upload, then upload the image, then create the post.\n\nStep 1: Initialize Image Upload\n\nPOST /linkedin/rest/images?action=initializeUpload\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"initializeUploadRequest\": {\n    \"owner\": \"urn:li:person:{personId}\"\n  }\n}\n\n\nResponse:\n\n{\n  \"value\": {\n    \"uploadUrlExpiresAt\": 1770541529250,\n    \"uploadUrl\": \"https://www.linkedin.com/dms-uploads/...\",\n    \"image\": \"urn:li:image:D4D10AQH4GJAjaFCkHQ\"\n  }\n}\n\n\nStep 2: Upload Image Binary\n\nPUT {uploadUrl from step 1}\nContent-Type: image/png\n\n{binary image data}\n\n\nStep 3: Create Image Post\n\nPOST /linkedin/rest/posts\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"author\": \"urn:li:person:{personId}\",\n  \"lifecycleState\": \"PUBLISHED\",\n  \"visibility\": \"PUBLIC\",\n  \"commentary\": \"Check out this image!\",\n  \"distribution\": {\n    \"feedDistribution\": \"MAIN_FEED\"\n  },\n  \"content\": {\n    \"media\": {\n      \"id\": \"urn:li:image:D4D10AQH4GJAjaFCkHQ\",\n      \"title\": \"Image Title\"\n    }\n  }\n}\n\nVisibility Options\nValue\tDescription\nPUBLIC\tViewable by anyone on LinkedIn\nCONNECTIONS\tViewable by 1st-degree connections only\nShare Media Categories\nValue\tDescription\nNONE\tText-only post\nARTICLE\tURL/article share\nIMAGE\tImage post\nVIDEO\tVideo post\nAd Library (Public Data)\n\nThe Ad Library API provides access to public advertising data on LinkedIn. These endpoints use the REST API with version headers.\n\nRequired Headers for Ad Library\nLinkedIn-Version: 202506\n\nSearch Ads\nGET /linkedin/rest/adLibrary?q=criteria&keyword={keyword}\n\n\nQuery parameters:\n\nkeyword (string): Search ad content (multiple keywords use AND logic)\nadvertiser (string): Search by advertiser name\ncountries (array): Filter by ISO 3166-1 alpha-2 country codes\ndateRange (object): Filter by served dates\nstart (integer): Pagination offset\ncount (integer): Results per page (max 25)\n\nExample - Search ads by keyword:\n\nGET /linkedin/rest/adLibrary?q=criteria&keyword=linkedin\n\n\nExample - Search ads by advertiser:\n\nGET /linkedin/rest/adLibrary?q=criteria&advertiser=microsoft\n\n\nResponse:\n\n{\n  \"paging\": {\n    \"start\": 0,\n    \"count\": 10,\n    \"total\": 11619543,\n    \"links\": [...]\n  },\n  \"elements\": [\n    {\n      \"adUrl\": \"https://www.linkedin.com/ad-library/detail/...\",\n      \"details\": {\n        \"advertiser\": {...},\n        \"adType\": \"TEXT_AD\",\n        \"targeting\": {...},\n        \"statistics\": {\n          \"firstImpressionDate\": 1704067200000,\n          \"latestImpressionDate\": 1706745600000,\n          \"impressionsFrom\": 1000,\n          \"impressionsTo\": 5000\n        }\n      },\n      \"isRestricted\": false\n    }\n  ]\n}\n\nSearch Job Postings\nGET /linkedin/rest/jobLibrary?q=criteria&keyword={keyword}\n\n\nNote: Job Library requires version 202506.\n\nQuery parameters:\n\nkeyword (string): Search job content\norganization (string): Filter by company name\ncountries (array): Filter by country codes\ndateRange (object): Filter by posting dates\nstart (integer): Pagination offset\ncount (integer): Results per page (max 24)\n\nExample:\n\nGET /linkedin/rest/jobLibrary?q=criteria&keyword=software&organization=google\n\n\nResponse includes:\n\njobPostingUrl: Link to job listing\njobDetails: Title, location, description, salary, benefits\nstatistics: Impression data\nMarketing API (Advertising)\n\nThe Marketing API provides access to LinkedIn's advertising platform. These endpoints use the versioned REST API.\n\nRequired Headers for Marketing API\nLinkedIn-Version: 202506\n\nList Ad Accounts\nGET /linkedin/rest/adAccounts?q=search\n\n\nReturns all ad accounts accessible by the authenticated user.\n\nResponse:\n\n{\n  \"paging\": {\n    \"start\": 0,\n    \"count\": 10,\n    \"links\": []\n  },\n  \"elements\": [\n    {\n      \"id\": 123456789,\n      \"name\": \"My Ad Account\",\n      \"status\": \"ACTIVE\",\n      \"type\": \"BUSINESS\",\n      \"currency\": \"USD\",\n      \"reference\": \"urn:li:organization:12345\"\n    }\n  ]\n}\n\nGet Ad Account\nGET /linkedin/rest/adAccounts/{adAccountId}\n\nCreate Ad Account\nPOST /linkedin/rest/adAccounts\nContent-Type: application/json\n\n{\n  \"name\": \"New Ad Account\",\n  \"currency\": \"USD\",\n  \"reference\": \"urn:li:organization:{orgId}\",\n  \"type\": \"BUSINESS\"\n}\n\nUpdate Ad Account\nPOST /linkedin/rest/adAccounts/{adAccountId}\nContent-Type: application/json\nX-RestLi-Method: PARTIAL_UPDATE\n\n{\n  \"patch\": {\n    \"$set\": {\n      \"name\": \"Updated Account Name\"\n    }\n  }\n}\n\nList Campaign Groups\n\nCampaign groups are nested under ad accounts:\n\nGET /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups\n\nCreate Campaign Group\nPOST /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups\nContent-Type: application/json\n\n{\n  \"name\": \"Q1 2026 Campaigns\",\n  \"status\": \"DRAFT\",\n  \"runSchedule\": {\n    \"start\": 1704067200000,\n    \"end\": 1711929600000\n  },\n  \"totalBudget\": {\n    \"amount\": \"10000\",\n    \"currencyCode\": \"USD\"\n  }\n}\n\nGet Campaign Group\nGET /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups/{campaignGroupId}\n\nUpdate Campaign Group\nPOST /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups/{campaignGroupId}\nContent-Type: application/json\nX-RestLi-Method: PARTIAL_UPDATE\n\n{\n  \"patch\": {\n    \"$set\": {\n      \"status\": \"ACTIVE\"\n    }\n  }\n}\n\nDelete Campaign Group\nDELETE /linkedin/rest/adAccounts/{adAccountId}/adCampaignGroups/{campaignGroupId}\n\nList Campaigns\n\nCampaigns are also nested under ad accounts:\n\nGET /linkedin/rest/adAccounts/{adAccountId}/adCampaigns\n\nCreate Campaign\nPOST /linkedin/rest/adAccounts/{adAccountId}/adCampaigns\nContent-Type: application/json\n\n{\n  \"campaignGroup\": \"urn:li:sponsoredCampaignGroup:123456\",\n  \"name\": \"Brand Awareness Campaign\",\n  \"status\": \"DRAFT\",\n  \"type\": \"SPONSORED_UPDATES\",\n  \"objectiveType\": \"BRAND_AWARENESS\",\n  \"dailyBudget\": {\n    \"amount\": \"100\",\n    \"currencyCode\": \"USD\"\n  },\n  \"costType\": \"CPM\",\n  \"unitCost\": {\n    \"amount\": \"5\",\n    \"currencyCode\": \"USD\"\n  },\n  \"locale\": {\n    \"country\": \"US\",\n    \"language\": \"en\"\n  }\n}\n\nGet Campaign\nGET /linkedin/rest/adAccounts/{adAccountId}/adCampaigns/{campaignId}\n\nUpdate Campaign\nPOST /linkedin/rest/adAccounts/{adAccountId}/adCampaigns/{campaignId}\nContent-Type: application/json\nX-RestLi-Method: PARTIAL_UPDATE\n\n{\n  \"patch\": {\n    \"$set\": {\n      \"status\": \"ACTIVE\"\n    }\n  }\n}\n\nDelete Campaign\nDELETE /linkedin/rest/adAccounts/{adAccountId}/adCampaigns/{campaignId}\n\nCampaign Status Values\nStatus\tDescription\nDRAFT\tCampaign is in draft mode\nACTIVE\tCampaign is running\nPAUSED\tCampaign is paused\nARCHIVED\tCampaign is archived\nCOMPLETED\tCampaign has ended\nCANCELED\tCampaign was canceled\nCampaign Objective Types\nObjective\tDescription\nBRAND_AWARENESS\tIncrease brand visibility\nWEBSITE_VISITS\tDrive traffic to website\nENGAGEMENT\tIncrease post engagement\nVIDEO_VIEWS\tMaximize video views\nLEAD_GENERATION\tCollect leads via Lead Gen Forms\nWEBSITE_CONVERSIONS\tDrive website conversions\nJOB_APPLICANTS\tAttract job applications\nOrganizations\nList Organization ACLs\n\nGet organizations the authenticated user has access to:\n\nGET /linkedin/rest/organizationAcls?q=roleAssignee\nLinkedIn-Version: 202506\n\n\nResponse:\n\n{\n  \"paging\": {\n    \"start\": 0,\n    \"count\": 10,\n    \"total\": 2\n  },\n  \"elements\": [\n    {\n      \"role\": \"ADMINISTRATOR\",\n      \"organization\": \"urn:li:organization:12345\",\n      \"state\": \"APPROVED\"\n    }\n  ]\n}\n\nGet Organization\nGET /linkedin/rest/organizations/{organizationId}\nLinkedIn-Version: 202506\n\nLookup Organization by Vanity Name\nGET /linkedin/rest/organizations?q=vanityName&vanityName={vanityName}\n\n\nExample:\n\nGET /linkedin/rest/organizations?q=vanityName&vanityName=microsoft\n\n\nResponse:\n\n{\n  \"elements\": [\n    {\n      \"vanityName\": \"microsoft\",\n      \"localizedName\": \"Microsoft\",\n      \"website\": {\n        \"localized\": {\"en_US\": \"https://news.microsoft.com/\"}\n      }\n    }\n  ]\n}\n\nGet Organization Share Statistics\nGET /linkedin/rest/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity={orgUrn}\n\n\nExample:\n\nGET /linkedin/rest/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:12345\n\nGet Organization Posts\nGET /linkedin/rest/posts?q=author&author={orgUrn}\n\n\nExample:\n\nGET /linkedin/rest/posts?q=author&author=urn:li:organization:12345\n\nMedia Upload (REST API)\n\nThe REST API provides modern media upload endpoints. All require version header LinkedIn-Version: 202506.\n\nInitialize Image Upload\nPOST /linkedin/rest/images?action=initializeUpload\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"initializeUploadRequest\": {\n    \"owner\": \"urn:li:person:{personId}\"\n  }\n}\n\n\nResponse:\n\n{\n  \"value\": {\n    \"uploadUrlExpiresAt\": 1770541529250,\n    \"uploadUrl\": \"https://www.linkedin.com/dms-uploads/...\",\n    \"image\": \"urn:li:image:D4D10AQH4GJAjaFCkHQ\"\n  }\n}\n\n\nUse the uploadUrl to PUT your image binary, then use the image URN in your post.\n\nInitialize Video Upload\nPOST /linkedin/rest/videos?action=initializeUpload\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"initializeUploadRequest\": {\n    \"owner\": \"urn:li:person:{personId}\",\n    \"fileSizeBytes\": 10000000,\n    \"uploadCaptions\": false,\n    \"uploadThumbnail\": false\n  }\n}\n\n\nResponse:\n\n{\n  \"value\": {\n    \"uploadUrlsExpireAt\": 1770541530110,\n    \"video\": \"urn:li:video:D4D10AQE_p-P_odQhXQ\",\n    \"uploadInstructions\": [\n      {\"uploadUrl\": \"https://www.linkedin.com/dms-uploads/...\"}\n    ]\n  }\n}\n\nInitialize Document Upload\nPOST /linkedin/rest/documents?action=initializeUpload\nContent-Type: application/json\nLinkedIn-Version: 202506\n\n{\n  \"initializeUploadRequest\": {\n    \"owner\": \"urn:li:person:{personId}\"\n  }\n}\n\n\nResponse:\n\n{\n  \"value\": {\n    \"uploadUrlExpiresAt\": 1770541530896,\n    \"uploadUrl\": \"https://www.linkedin.com/dms-uploads/...\",\n    \"document\": \"urn:li:document:D4D10AQHr-e30QZCAjQ\"\n  }\n}\n\nAd Targeting\nGet Available Targeting Facets\nGET /linkedin/rest/adTargetingFacets\n\n\nReturns all available targeting facets for ad campaigns (31 facets including employers, degrees, skills, locations, industries, etc.).\n\nResponse:\n\n{\n  \"elements\": [\n    {\n      \"facetName\": \"skills\",\n      \"adTargetingFacetUrn\": \"urn:li:adTargetingFacet:skills\",\n      \"entityTypes\": [\"SKILL\"],\n      \"availableEntityFinders\": [\"AD_TARGETING_FACET\", \"TYPEAHEAD\"]\n    },\n    {\n      \"facetName\": \"industries\",\n      \"adTargetingFacetUrn\": \"urn:li:adTargetingFacet:industries\"\n    }\n  ]\n}\n\n\nAvailable targeting facets include:\n\nskills - Member skills\nindustries - Industry categories\ntitles - Job titles\nseniorities - Seniority levels\ndegrees - Educational degrees\nschools - Educational institutions\nemployers / employersPast - Current/past employers\nlocations / geoLocations - Geographic targeting\ncompanySize - Company size ranges\ngenders - Gender targeting\nageRanges - Age range targeting\nGetting Your Person ID\n\nTo create posts, you need your LinkedIn person ID. Get it from the /rest/me endpoint:\n\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://gateway.maton.ai/linkedin/rest/me')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nreq.add_header('LinkedIn-Version', '202506')\nresult = json.load(urllib.request.urlopen(req))\nprint(f\"Your person URN: urn:li:person:{result['id']}\")\nEOF\n\nCode Examples\nJavaScript - Create Text Post\nconst personId = 'YOUR_PERSON_ID';\n\nconst response = await fetch(\n  'https://gateway.maton.ai/linkedin/rest/posts',\n  {\n    method: 'POST',\n    headers: {\n      'Authorization': `Bearer ${process.env.MATON_API_KEY}`,\n      'Content-Type': 'application/json',\n      'LinkedIn-Version': '202506'\n    },\n    body: JSON.stringify({\n      author: `urn:li:person:${personId}`,\n      lifecycleState: 'PUBLISHED',\n      visibility: 'PUBLIC',\n      commentary: 'Hello from the API!',\n      distribution: {\n        feedDistribution: 'MAIN_FEED'\n      }\n    })\n  }\n);\n\nPython - Create Text Post\nimport os\nimport requests\n\nperson_id = 'YOUR_PERSON_ID'\n\nresponse = requests.post(\n    'https://gateway.maton.ai/linkedin/rest/posts',\n    headers={\n        'Authorization': f'Bearer {os.environ[\"MATON_API_KEY\"]}',\n        'Content-Type': 'application/json',\n        'LinkedIn-Version': '202506'\n    },\n    json={\n        'author': f'urn:li:person:{person_id}',\n        'lifecycleState': 'PUBLISHED',\n        'visibility': 'PUBLIC',\n        'commentary': 'Hello from the API!',\n        'distribution': {\n            'feedDistribution': 'MAIN_FEED'\n        }\n    }\n)\n\nRate Limits\nThrottle Type\tDaily Limit (UTC)\nMember\t150 requests/day\nApplication\t100,000 requests/day\nNotes\nPerson IDs are unique per application and not transferable across apps\nThe author field must use URN format: urn:li:person:{personId}\nAll posts require lifecycleState: \"PUBLISHED\"\nImage/video uploads are a 3-step process: initialize upload, upload binary, create post\nInclude LinkedIn-Version: 202506 header for all REST API calls\nProfile picture URLs may expire; re-fetch if needed\nIMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing\nIMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments\nError Handling\nStatus\tMeaning\n400\tMissing LinkedIn connection or invalid request\n401\tInvalid or missing Maton API key\n403\tInsufficient permissions (check OAuth scopes)\n404\tResource not found\n422\tInvalid request body or URN format\n429\tRate limited\n4xx/5xx\tPassthrough error from LinkedIn API\nError Response Format\n{\n  \"status\": 403,\n  \"serviceErrorCode\": 100,\n  \"code\": \"ACCESS_DENIED\",\n  \"message\": \"Not enough permissions to access resource\"\n}\n\nTroubleshooting: API Key Issues\nCheck that the MATON_API_KEY environment variable is set:\necho $MATON_API_KEY\n\nVerify the API key is valid by listing connections:\npython <<'EOF'\nimport urllib.request, os, json\nreq = urllib.request.Request('https://ctrl.maton.ai/connections')\nreq.add_header('Authorization', f'Bearer {os.environ[\"MATON_API_KEY\"]}')\nprint(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))\nEOF\n\nTroubleshooting: Invalid App Name\nEnsure your URL path starts with linkedin. For example:\nCorrect: https://gateway.maton.ai/linkedin/rest/me\nIncorrect: https://gateway.maton.ai/rest/me\nOAuth Scopes\nScope\tDescription\nopenid\tOpenID Connect authentication\nprofile\tRead basic profile\nemail\tRead email address\nw_member_social\tCreate, modify, and delete posts\nResources\nLinkedIn API Overview\nShare on LinkedIn Guide\nProfile API\nSign In with LinkedIn\nAuthentication Guide\nMarketing API\nAd Accounts\nCampaign Management\nAd Library API\nMaton Community\nMaton Support"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/byungkyu/linkedin-api",
    "publisherUrl": "https://clawhub.ai/byungkyu/linkedin-api",
    "owner": "byungkyu",
    "version": "1.0.3",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/linkedin-api",
    "downloadUrl": "https://openagent3.xyz/downloads/linkedin-api",
    "agentUrl": "https://openagent3.xyz/skills/linkedin-api/agent",
    "manifestUrl": "https://openagent3.xyz/skills/linkedin-api/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/linkedin-api/agent.md"
  }
}