-
Notifications
You must be signed in to change notification settings - Fork 0
Authorship Intake
The Authorship endpoint lets API clients submit and retrieve Authorship intake data for reseller-owned accounts and campaigns.
This endpoint is used when a campaign has an Authorship workflow task and the reseller needs to provide author profile information, LinkedIn details, optional biography content, and an optional author image.
All requests require API authorization using the same Bearer JWT and/or API key authentication used by other Semify v1 API endpoints.
/api/v1/authorship| Method | Path | Purpose |
|---|---|---|
POST |
/api/v1/authorship |
Create Authorship intake data |
GET |
/api/v1/authorship |
List Scheduled Authorship tasks |
Creates a new Authorship intake record for a reseller-owned account and campaign.
When successful, this endpoint:
- Verifies the authenticated reseller owns the account.
- Verifies the reseller owns the campaign.
- Confirms an Authorship task exists for the campaign.
- Requires the Authorship task to be in Scheduled status.
- Prevents duplicate intake records for the same account and campaign.
- Inserts a row into
authorship_intake. - Inserts related content rows into
authorship_intake_content. - Updates the task
link_imagewhen a valid image URL is supplied. - Adds a task note containing the submitted intake details.
- Optionally creates a LinkedIn entry in the campaign password locker.
{
"account": {
"account_id": 12345,
"camp_id": 54321
},
"author": {
"full_name": "Jane Doe",
"position": "Editor",
"business_name": "Example Co"
},
"linked_in": {
"url": "https://www.linkedin.com/in/janedoe"
}
}| Field | Type | Description |
|---|---|---|
account.account_id |
integer | Account ID for the intake |
account.camp_id |
integer | Campaign ID for the intake |
author.full_name |
string | Author’s full name |
author.position |
string | Author’s title or position |
author.business_name |
string | Business name associated with the author |
linked_in |
object | LinkedIn information object |
| Field | Type | Description |
|---|---|---|
linked_in.url |
string | Public LinkedIn profile URL |
linked_in.username |
string | LinkedIn username for password locker storage |
linked_in.password |
string | LinkedIn password, stored encrypted |
link_image |
string | Author image URL |
experience_history |
string | Author experience/history |
interests_facts |
string | Interests or notable facts |
areas_expertise |
string | Areas of expertise |
education |
string | Education details |
current_work |
string | Current work details |
credentials |
string | Credentials or certifications |
pub_awards |
string | Publications or awards |
The linked_in object is required, but its child fields are optional.
If only linked_in.url is supplied, the API stores the URL on the intake and may create a LinkedIn password locker entry with the URL in the note field.
If both linked_in.username and linked_in.password are supplied, the password is encrypted before storage and saved for internal password locker workflows.
Always submit LinkedIn credentials over HTTPS.
If link_image is supplied, the API normalizes and validates it.
If the URL does not start with http:// or https://, the API prepends https://.
The image URL is only kept if it contains one of the following extensions:
.png.gif.jpg.jpeg.bmp
If the image URL does not contain one of those extensions, the value is cleared.
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"account": {
"account_id": 12345,
"camp_id": 54321
},
"author": {
"full_name": "Jane Doe",
"position": "Editor",
"business_name": "Example Co"
},
"linked_in": {
"url": "https://www.linkedin.com/in/janedoe"
},
"link_image": "https://example.com/photo.jpg",
"credentials": "Certified Example",
"experience_history": "10 years in SEO"
}' \
"https://uat.services.semify.com/api/v1/authorship"curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"account": {
"account_id": 12345,
"camp_id": 54321
},
"author": {
"full_name": "Jane Doe",
"position": "Editor",
"business_name": "Example Co"
},
"linked_in": {
"url": "https://www.linkedin.com/in/janedoe",
"username": "user@example.com",
"password": "useStrongSecretsOnlyOnHTTPS"
}
}' \
"https://uat.services.semify.com/api/v1/authorship"{
"data": {},
"error": false,
"messages": [
"Authorship created successfully",
"Success"
]
}Returned when an intake already exists for the same account and campaign.
{
"data": {},
"error": true,
"messages": [
"An intake already exists for this account and campaign. - errorcode: authorship-v1-create:2",
"Bad Request"
]
}{
"data": {},
"error": true,
"messages": [
"The reseller does not own this account. - errorcode: authorship-v1-create:2",
"Bad Request"
]
}{
"data": {},
"error": true,
"messages": [
"The reseller does not own this campaign. - errorcode: authorship-v1-create:3",
"Bad Request"
]
}{
"data": {},
"error": true,
"messages": [
"Account does not have Authorship plans - errorcode: authorship-v1-create:4",
"Bad Request"
]
}{
"data": {},
"error": true,
"messages": [
"Task must be in Scheduled status (status_id = 1) to submit an intake. Current status: 2 - errorcode: authorship-v1-create:3",
"Bad Request"
]
}Returns Scheduled Authorship tasks for the authenticated reseller.
The endpoint only returns tasks that match the Authorship task type and are not completed.
Authorship task rules:
task_type_id = 136status_id = 1date_completed IS NULL- Campaign must belong to the authenticated reseller
| Parameter | Type | Required | Description |
|---|---|---|---|
account_id |
integer | No | Filter by account ID |
camp_id |
integer | No | Filter by campaign ID |
start_date |
date | No | Filter by task due date greater than or equal to this date |
end_date |
date | No | Filter by task due date less than or equal to this date |
needsIntakeData |
boolean | No |
true returns tasks without intake data; false returns tasks with intake data |
Dates should use YYYY-MM-DD format.
curl -H "Authorization: Bearer $TOKEN" \
"https://uat.services.semify.com/api/v1/authorship?account_id=12345&needsIntakeData=true"{
"data": [
{
"task_id": 1001,
"camp_id": 54321,
"task_name": "Content - Website Authorship Page",
"task_type_id": 136,
"task_type_name": "Authorship",
"camp_name": "Example Campaign",
"account_id": 12345,
"status": "Scheduled",
"date_due": "2026-05-15",
"created_date": "2026-05-01",
"intake_id": null
}
],
"error": false,
"messages": [
"Successfully retrieved 1 scheduled Authorship tasks",
"with filters: account_id: 12345, needsIntakeData: true"
]
}| Field | Description |
|---|---|
task_id |
Task ID |
camp_id |
Campaign ID |
task_name |
Task name |
task_type_id |
Task type ID, expected to be 136
|
task_type_name |
Display name for the task type |
camp_name |
Campaign name |
account_id |
Account ID |
status |
Task status |
date_due |
Task due date |
created_date |
Task creation date |
intake_id |
Authorship intake ID, or null if intake data has not been submitted |
Invalid dates, invalid date ranges, or invalid needsIntakeData values may return a validation error.
{
"data": {},
"error": true,
"messages": [
"start_date must be in YYYY-MM-DD format; needsIntakeData must be either 'true' or 'false'"
]
}{
"data": {},
"error": true,
"messages": [
"No authorship tasks found"
]
}- Use
GET /api/v1/authorship?needsIntakeData=trueto find Scheduled Authorship tasks that still need intake data. - Select the desired
account_idandcamp_idfrom the returned task. - Submit
POST /api/v1/authorshipwith the author profile, LinkedIn object, and optional content fields. - Use
GET /api/v1/authorship?account_id={account_id}&camp_id={camp_id}&needsIntakeData=falseto confirm the intake is attached.
- Only one intake can exist per
account_idandcamp_id. - The Authorship task must be Scheduled before intake data can be submitted.
-
start_dateandend_datefilter against task due date, not task creation date. - LinkedIn passwords are encrypted before storage.
- Do not submit LinkedIn credentials over non-HTTPS connections.
-
link_imagemust point to a common raster image type or it will be ignored.