This module publishes on the LinkedIn company pages an Odoo user
administrates, and keeps the daily figures of those pages.
Everything it asks LinkedIn for costs a fixed number of calls per
account or per publication, so what it costs does not change whether a
page published once or ten thousand times. Reading back what the page
already published — importing the publications, their comments and
their reactions — grows with that history and lives in Social Media
LinkedIn Sync, which installs on its own as soon as Social Media Sync
is present.
System parameters
Nothing here has to be set for the connector to work: each key defaults
to the value the code carries, and it only exists once it is written by
hand in Settings > Technical > Parameters > System Parameters.
They are bounded when they are read, so a value outside its range is
brought back into it instead of being obeyed.
| Parameter |
Default |
Unit |
Bounds |
| social_media_linkedin.video_poll_attempts |
30 |
polls |
at least 1, and
at most what the
600 second
ceiling allows |
| social_media_linkedin.video_poll_delay |
2 |
seconds between
polls |
at least 1 |
The two are the wait LinkedIn needs to finish processing an uploaded
video before the post can be published, and what matters is their
product: it is time the publication spends inside its own transaction.
Past the limit_time_real of the deployment — 120 seconds by default,
and the scheduled actions inherit it — the worker is killed with the
video already uploaded on LinkedIn and nothing published in Odoo. That
is why the number of polls is cut down to what 600 seconds allow at the
delay in force, and why raising the wait for a long video means raising
limit_time_real as well. A delay longer than the ceiling itself is
not cut: it becomes one single wait, and setting one is asking for the
worker to be killed.
Below their bounds the numbers stop making sense rather than merely
being small: zero polls publishes nothing without ever asking LinkedIn,
and a delay under a second turns the wait into a burst against an API
whose rate limit the module does not manage.
Usage
List of posts generated from Odoo.
Only posts generated using Odoo are displayed.
- Go to Social Media > Posts
- Opening a publication, from its form or from its card on the
dashboard, reads it on LinkedIn first. One that was deleted there is
reported as The post does not exist or has been deleted. and marked
as Deleted on the spot, keeping its reference. Only a 404 counts
as a deletion: a lost page role or a throttled application leaves the
publication alone, because a publication is not gone just because Odoo
could not read it.
Generate a post.
This feature acts as a template for generating multiple posts from a
single view, depending on the selected accounts.
- Go to Social Media > Posts > New or Go to Social Media > Dashboard
> Add Post
- Fill in the required fields
- When the post is created, every LinkedIn account of the active company
is selected by default in Accounts; remove the ones you do not want
to use before publishing.

- Save
- Click on the Post button
- LinkedIn publishes either images or a video, never both: when the post
carries a video, its images are left out. The preview of the post says
so by showing the video alone, so what is previewed is what LinkedIn
receives, and a banner on the form explains it as well.
- A publication shares the images and the video of its post, so the
dashboard card shows them as soon as LinkedIn accepts the post and
nothing else has to run. What LinkedIn made of each media is recorded
on the publication, which is what lets an image deleted on LinkedIn
leave the card while the one in the post stays; noticing that deletion
needs Social Media LinkedIn Sync.
LinkedIn limits and validations
What LinkedIn refuses is checked in Odoo before the publication is sent.
The post shows the reason while it is being written, saving is never
blocked, and the publication of the account that raises the objection is
refused instead of being sent and failing on LinkedIn. The same checks
are applied when the post reaches the publication through an import or
an RPC call, so nothing gets past them.
- The message is checked against 3000 characters, the length the
commentary field of the Posts
API
takes. A longer message is reported on the post and the publication is
not sent.
- The images are checked against 20 per post, against the formats
LinkedIn publishes, JPG, PNG and GIF, and against 10 MB each.
One image is published as a single image and two or more as a
multi-image
post.
The message names the files that cannot be published.
- The video is checked against one per post, against MP4 and
against 500 MB.
- A post carrying images and a video is not refused: LinkedIn publishes
the video and leaves the images out, so the post is told what goes out
instead of being stopped. That is also why the image rules are not
applied at all to a post carrying a video — its images decide nothing.
- The file picker only filters what the browser proposes, so a file
added by drag and drop reaches the checks all the same, and they are
what refuses the ones LinkedIn does not take.
- What is left to LinkedIn is everything about the content itself: the
dimensions and the aspect ratio of an image, the codecs and the
duration of a video, the text it reads as spam. Nothing of that is
checked here, and a publication LinkedIn refuses for one of those
reasons is left as Failed with the validation error it answered.
- Every call to LinkedIn has a timeout of 10 seconds, not
configurable. If LinkedIn or the connection take longer, the operation
fails with Error connecting to LinkedIn and has to be retried; a
publication is left as Failed and can be sent again with the Post
button.
- An account without an access token does not publish: this is what
happens after uninstalling and installing the module back, which
clears the credentials. The line is left as Failed stating that the
account has no access token, and the account shows the update warning.
Authorize it again with Update account.
- Recommending a publication or one of its comments, and reading those
comments back, is served by Social Media LinkedIn Sync: this module
draws none of those buttons and never calls the Reactions API.
- Deleting a publication from the dashboard deletes it on LinkedIn
first. If LinkedIn does not confirm the deletion, the operation is
cancelled with Error deleting LinkedIn post and the record is kept
in Odoo, so the two sides never get out of sync.
Maintainers
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
Current maintainer:

This module is part of the OCA/social project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Social Media Linkedin
This module publishes on the LinkedIn company pages an Odoo user administrates, and keeps the daily figures of those pages.
Everything it asks LinkedIn for costs a fixed number of calls per account or per publication, so what it costs does not change whether a page published once or ten thousand times. Reading back what the page already published — importing the publications, their comments and their reactions — grows with that history and lives in Social Media LinkedIn Sync, which installs on its own as soon as Social Media Sync is present.
Main features:
Statistics account
The eye icon: Total number of views, which may include multiple views by the same user.
The hand icon: the interactions (clicks, likes, comments and shares) the page accumulated over the days of the series.
The star icon: the engagement of the account, its interactions over its impressions, shown as a percentage. The engagement LinkedIn reports by day is kept on each row of the time series and read in the graph and pivot views; it is never averaged into the card.
Table of contents
Configuration
To configure this module, you need to:
Please note that you must have a developer account. The steps required for using it are defined below:
Before creating this developer account, you must have a partner company on your LinkedIn account and be an administrator.
Only company pages (organizations) can be linked, never personal profiles: a post is always published on behalf of the organization. Odoo only reads the organizations where the member who authorizes is an ADMINISTRATOR whose invitation has already been accepted (APPROVED state). If your role is still pending, LinkedIn does not return the organization and the wizard ends without creating any account.
The connector needs no additional Python library: it uses requests, which is already shipped with Odoo, so there is nothing to install on the server besides the module itself.
Go to https://developer.linkedin.com/
Create a new Developer App with the Create app button.
Fill in the requested fields. In the Privacy Policy URL field, copy your company’s URL.
Once the app is created, go to the My Apps menu and you will see the newly created app; select it.
Within the app, in the Settings tab, verify your company. You will see a button that says Verify. Click it, and in the window that appears in the lower left corner, click the Generate URL button. Copy the generated URL into your browser and accept.
Then go to the Products tab and request access to the products granting the scopes the installed modules ask for:
Note that some products require you to fill out a form; you must do so, otherwise, the necessary scopes for basic use of your account will not be enabled. The products, the scopes they grant and the versions of the API are described in the LinkedIn Marketing API documentation and in its versioning guide.
After requesting the aforementioned Products, go to the Auth tab and you will see all the enabled scopes at the bottom.
Each module asks for the permissions its own calls consume, so what is requested depends on what is installed:
All of them have to appear enabled in the Auth tab of your App; if one is missing, LinkedIn refuses the whole authorization and the Product that grants it has to be requested. LinkedIn does not let the member pick part of them either: the consent screen is all or nothing, which is why nothing is requested “just in case”.
What LinkedIn granted is stored on the account, in the Granted Scopes field of its Configuration tab, so a permission error can be read there instead of in the logs. That same field is what the next authorization requests, and it can be edited:
Editing the field on its own changes nothing, and ticking only Update token is not enough either: refreshing a token keeps the scopes it was granted, only a new authorization can ask for more. Go straight to Update account after editing the field, because Validate token and any token refresh rewrite it with the scopes LinkedIn reports, and the additions typed by hand are lost. Beware that a scope the Products of your App do not grant makes LinkedIn refuse the whole authorization, and the account cannot be authorized again until it is removed from the field.
Every call to the versioned REST API carries the LinkedIn-Version: 202607 and X-Restli-Protocol-Version: 2.0.0 headers. The OAuth calls of the association — the code-for-token exchange and the token introspection — and the download of the organization logo do not. LinkedIn retires each version of the API about a year after publishing it, so the module has to be updated periodically: once the version is no longer supported, LinkedIn answers every request with a version error.
At the top of the aforementioned tab, you will see the Client ID and Primary Client Secret information.
Configure the access points for which you want to use the account. Follow these steps:
Registering the Client ID and Client Secret. Integration of a user account.
Go to Social Media > Configuration > Social Media
Click on the Associate Account button for the desired social media.
A wizard will open for you to add the Client ID and Client Secret obtained from your developer account.
By clicking the Associate button here, you’ll be taken to a LinkedIn authentication page. Once you validate your information, LinkedIn brings you back to Odoo: if the association succeeded you land directly on the Social Media Dashboard with a success notification, and if it failed you come back to the start screen with the notification of the error.
Once you have completed these steps and everything is working correctly, you can see your account in Social Media > Configuration > Accounts
After the account is associated, the daily figures of the page are read and the card of the dashboard is filled. Importing what the page already published needs Social Media LinkedIn Sync.
Note that the account credentials (Client ID, Client Secret and tokens) are masked and only visible to administrator users.
The authorization flow is bound to the session that started it: the state token sent to LinkedIn only works for the user who opened the wizard, and it is discarded once the flow ends, so the same authorization cannot be replayed. If the state does not match, the association is refused with Invalid OAuth state token. Please restart the account association process. The flow itself is the one described in the authorization code flow of LinkedIn.
If the LinkedIn organization is already linked to an account of another Odoo user, the association is refused and nothing is overwritten: only the responsible user of the account and the Social Media / Administrator group can relink it.
Every account has to use its own credentials: if the Client ID and the Client Secret are already registered on another account, the association is refused with An account with this information already exists; please also check archived accounts. The check includes the archived accounts, which keep their credentials, so check the Archived filter as well before trying again. To reauthorize an existing account, use its Update account button instead of the wizard.
System parameters
Nothing here has to be set for the connector to work: each key defaults to the value the code carries, and it only exists once it is written by hand in Settings > Technical > Parameters > System Parameters. They are bounded when they are read, so a value outside its range is brought back into it instead of being obeyed.
The two are the wait LinkedIn needs to finish processing an uploaded video before the post can be published, and what matters is their product: it is time the publication spends inside its own transaction. Past the limit_time_real of the deployment — 120 seconds by default, and the scheduled actions inherit it — the worker is killed with the video already uploaded on LinkedIn and nothing published in Odoo. That is why the number of polls is cut down to what 600 seconds allow at the delay in force, and why raising the wait for a long video means raising limit_time_real as well. A delay longer than the ceiling itself is not cut: it becomes one single wait, and setting one is asking for the worker to be killed.
Below their bounds the numbers stop making sense rather than merely being small: zero polls publishes nothing without ever asking LinkedIn, and a delay under a second turns the wait into a burst against an API whose rate limit the module does not manage.
Usage
List of posts generated from Odoo.
Only posts generated using Odoo are displayed.
Generate a post.
This feature acts as a template for generating multiple posts from a single view, depending on the selected accounts.
Update token, client ID, client Secret and organization data
Go to Social Media > Configuration > Accounts
Select the account
Click on the Update account button
In the wizard that appears, if none of the checkboxes are selected and the Update button is pressed, the system will update only the organization’s data.
If the Update keys checkbox is selected, the current Client ID is proposed to the administrator users, the only ones allowed to read it, and the Client Secret has to be typed again: the stored secret is never sent to the browser. Authentication is then performed again through LinkedIn, and the keys are only written on the account once LinkedIn has accepted them, so an authorization left halfway keeps the credentials that still work.
Selecting the Update token checkbox will update the current token.
Validate the token
Go to Social Media > Configuration > Accounts
Select the account and open the Configuration tab
Click on the Validate token button. It always asks LinkedIn whether the token is still active, because a token can be revoked there long before the stored expiry dates: a notification confirms that it is valid, and if it is not, the token is renewed. Outside the renewal window, the check made before every call to LinkedIn uses the stored dates, so it costs no extra request.
Archive Account Linkedin
Go to Social Media > Configuration > Accounts
Select the account and pick Archive in the Actions menu of the form.
Please note that all data associated with this account will be archived.
If you associate the same LinkedIn account again later, the archived account and its related data will be reactivated instead of creating a duplicate.
An archived account can be deleted permanently with the Delete permanently button, only available to a social media administrator. The LinkedIn publications stay online, only the Odoo history is removed.
Uninstalling the module
Uninstalling Social Media Linkedin does not delete the accounts nor their publication history:
Time series of the account
Figures of a publication
LinkedIn tokens
LinkedIn limits and validations
What LinkedIn refuses is checked in Odoo before the publication is sent. The post shows the reason while it is being written, saving is never blocked, and the publication of the account that raises the objection is refused instead of being sent and failing on LinkedIn. The same checks are applied when the post reaches the publication through an import or an RPC call, so nothing gets past them.
Video upload
LinkedIn decides how a video is split: initializeUpload answers one instruction per part, of 4 MiB each except the last one, and every part is uploaded with its own request. The identifiers LinkedIn returns for the parts are sent back to finalizeUpload in the same order, so the video is put together as it was cut. A 22 MB video takes 6 parts, and publishing then waits for LinkedIn to finish processing it, up to 30 polls two seconds apart.
https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/videos-api
A post publishes a single video, so a post carrying several is refused before uploading anything: LinkedIn would only keep the first one and the others would be transferred and processed for nothing.
LinkedIn processes an uploaded video before it can be published, so publishing a post with a video waits until the video is available: 30 attempts every 2 seconds, which a long video may need more than. Both numbers are system parameters, described in CONFIGURE.
The publication shares the video of its post the same way it shares its images, and what LinkedIn made of it is recorded in its media references. The camera icon without a count is the fallback drawn for a publication that carries only the has video flag — one imported from LinkedIn, whose video was never downloaded and can only be watched there.
Publishing options
Every publication is created public, in the main feed, with no targeting by country, language or industry, and letting it be shared: visibility, feedDistribution, targetEntities and thirdPartyDistributionChannels are fixed in the code.
Scheduling is not delegated to LinkedIn either: the Odoo scheduled action is the one that publishes when the date arrives.
https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/posts-api
Errors reported by LinkedIn
Known issues / Roadmap
Publishing options are not configurable
The visibility, the feed distribution, the targeting by country, language or industry and the third party distribution are fixed in the code, so a publication cannot be restricted nor targeted from Odoo. Offering them means exposing them on the post and validating the combinations LinkedIn accepts.
https://learn.microsoft.com/en-us/linkedin/marketing/community-management/shares/posts-api
Duration, codecs, dimensions and aspect ratio of a video are not checked
Rate limits are not handled
Bug Tracker
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed feedback.
Do not contact contributors directly about support or help with technical issues.
Credits
Authors
Contributors
Other credits
This work has been funded by AEOdoo (Asociación Española de Odoo - https://www.aeodoo.org)
Maintainers
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.
Current maintainer:
This module is part of the OCA/social project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.