st.doForSkills
This action allows you to endorse each skill provided by the parent action, or only the skills whose names match the patterns you specify.
This action cannot start a workflow on its own. The Node SDK's endorsePersonSkills method runs it for you: it opens the profile, reads the skills and endorses the ones skillNamePatterns selects, or all of them. To combine it with other actions, put it under st.retrievePersonSkills in the workflow you pass to customWorkflow – see Building Workflows.
This action cannot start a workflow on its own. The Python SDK's endorse_person_skills method runs it for you: it opens the profile, reads the skills and endorses the ones skill_name_patterns selects, or all of them. To combine it with other actions, put it under st.retrievePersonSkills in the workflow you pass to custom_workflow, where the action keeps its JSON keys such as skillNamePatterns – see Building Workflows.
This action cannot start a workflow on its own. linkedin person endorse <url> --pattern <re>… (or --all) runs it for you: it opens the profile, reads the skills and endorses the ones the patterns select – see Endorsing skills for the CLI rules. To combine it with other actions, put it under st.retrievePersonSkills in the workflow you pass to linkedin workflow run.
Skill names are shown as the profile owner entered them, in the owner's language, whatever your own LinkedIn language. A German profile lists
Projektmanagement, notProject Management. Write patterns in the language of the profiles you target, or cover several languages in one pattern, such as"proje[ck]t\\s*management".
Constraints
⏺️ Root Start: not allowed.
⬆️ Parent Actions: st.retrievePersonSkills.
⬇️ Child Actions: st.endorsePersonSkill.
Parameters
{
"actionType": "st.doForSkills",
"skillNamePatterns": ["business", "project\\s*manage", "^(agile|scrum)$"],
"then": {
"actionType": "st.endorsePersonSkill"
}
}skillNamePatterns(optional) – array of regular expressions that select skills by name. A skill is selected when any of the patterns matches its name. If omitted, every skill is selected.- The syntax is RE2, the dialect of Go
regexpand Google SheetsREGEXMATCH. Ordinary patterns read like JavaScript regular expressions, but lookaround ((?=…),(?!…),(?<=…),(?<!…)) and backreferences (\1) are not supported. - Matching is case-insensitive and searches anywhere in the name:
managematchesProject Management. To require the whole name to match, anchor the pattern with^…$:^scrum$matchesScrumbut notScrum Master. - Patterns are JSON strings, so each backslash is written twice:
"project\\s*manage"is the regular expressionproject\s*manage. The CLI's--pattern, in single quotes, takes the regular expression as is, with one backslash:--pattern 'project\s*manage'. - The array holds 1 to 20 patterns, each 1 to 200 characters long. An empty array, more than 20 patterns, an empty pattern, a pattern longer than 200 characters, or a pattern that is not valid RE2 (including lookaround, backreferences and repetition counts above 1000) is rejected with
invalidWorkflowbefore the workflow starts. - The patterns together must also stay within a matching-cost budget: their compiled RE2 programs may hold at most 5000 instructions in total. Ordinary patterns are far below it – 20 alternations of 200 characters each come to about 3700. Large repetition counts are what spend it:
.{0,1000}alone costs about 2000, so three of them across the array exceed the budget and the workflow is rejected withinvalidWorkflow.
- The syntax is RE2, the dialect of Go
then(required) – exactly one st.endorsePersonSkill action withoutskillName, as an object or a one-element array. The skill to endorse comes from the iteration.
Result options
This action doesn't produce its own distinct result. Its effects are visible in the skills returned by st.retrievePersonSkills:
- The parent's
datastill lists every skill of the person. - A selected skill carries a
thenfield: an array with the result of its st.endorsePersonSkill, successful or failed. - A skill the patterns did not select has no
thenfield.
Selected skills are endorsed one at a time, in the order they appear on the profile. A failed endorsement is reported in that skill's then, and the next selected skill is still processed. Each successful endorsement counts toward the stEndorsements limit, which is checked before each selected skill: once it is reached, skills get limitExceeded in their then and are not endorsed until earlier endorsements fall outside the limit period, so a later skill can still succeed. Check the then of every selected skill. If the person is not your 1st-degree connection, every selected skill gets connectionNotFound and nothing is endorsed.
Usage examples
- Endorsing only skills related to business and project management:
Workflow:
{
"actionType": "st.openPersonPage",
"personUrl": "https://www.linkedin.com/in/person1",
"basicInfo": false,
"then": {
"actionType": "st.retrievePersonSkills",
"then": {
"actionType": "st.doForSkills",
"skillNamePatterns": ["business", "project\\s*manage", "^(agile|scrum)$"],
"then": {
"actionType": "st.endorsePersonSkill"
}
}
}
}Completion:
Result – result() returns in data one item per selected skill, with skillName, success and error; skills the patterns did not select are left out. Check every item: errors only covers failures to open the profile or read its skills.
Result – result() returns in data one PersonSkillEndorsement per selected skill, with skill_name, success and error; skills the patterns did not select are left out. Check every item: errors only covers failures to open the profile or read its skills.
Output – linkedin person endorse prints one item per selected skill, with skillName, success and error, as data; skills the patterns did not select are left out. This is the JSON it prints with --json or into a pipe; check every item.
{
"actionType": "st.openPersonPage",
"success": true,
"data": {
"then": {
"actionType": "st.retrievePersonSkills",
"success": true,
"data": [
{
"name": "Business Strategy",
"then": [
{
"actionType": "st.endorsePersonSkill",
"success": true
}
]
},
{
"name": "Python"
},
{
"name": "Project Management",
"then": [
{
"actionType": "st.endorsePersonSkill",
"success": true
}
]
},
{
"name": "Agile Coaching"
},
{
"name": "Scrum",
"then": [
{
"actionType": "st.endorsePersonSkill",
"success": false,
"error": {
"type": "limitExceeded",
"message": "The configured limit for this action category has been exceeded."
}
}
]
}
]
}
}
}Python matches none of the patterns. Agile Coaching is not selected either, because ^(agile|scrum)$ must match the whole name. Scrum was selected, but the account had reached its endorsement limit by then, so it was not endorsed.
- Endorsing every skill of a person:
Workflow:
{
"actionType": "st.openPersonPage",
"personUrl": "https://www.linkedin.com/in/person1",
"basicInfo": false,
"then": {
"actionType": "st.retrievePersonSkills",
"then": {
"actionType": "st.doForSkills",
"then": {
"actionType": "st.endorsePersonSkill"
}
}
}
}Completion:
Result – result() returns in data one item per selected skill, with skillName, success and error; skills the patterns did not select are left out. Check every item: errors only covers failures to open the profile or read its skills.
Result – result() returns in data one PersonSkillEndorsement per selected skill, with skill_name, success and error; skills the patterns did not select are left out. Check every item: errors only covers failures to open the profile or read its skills.
Output – linkedin person endorse prints one item per selected skill, with skillName, success and error, as data; skills the patterns did not select are left out. This is the JSON it prints with --json or into a pipe; check every item.
{
"actionType": "st.openPersonPage",
"success": true,
"data": {
"then": {
"actionType": "st.retrievePersonSkills",
"success": true,
"data": [
{
"name": "Business Strategy",
"then": [
{
"actionType": "st.endorsePersonSkill",
"success": true
}
]
},
{
"name": "Python",
"then": [
{
"actionType": "st.endorsePersonSkill",
"success": true
}
]
}
]
}
}
}