Webhooks
Subscribe to real-time events in your Oktopost account and receive instant notifications via HTTP callbacks.
Webhooks enable you to build integrations that subscribe to events happening in your Oktopost account. When an event occurs, Oktopost sends an HTTP POST request to the URL you specify, allowing you to trigger automated workflows, sync data to external systems, or build custom notifications.
How Webhooks Work
- Create a webhook - Specify which event to monitor and where to send notifications
- Event occurs - When the subscribed event happens in Oktopost, a webhook is triggered
- Receive notification - Oktopost sends an HTTP POST request to your endpoint with event details
- Process the event - Your application receives and processes the webhook payload
Webhooks are sent in real-time as events occur. For event history and debugging, use the Webhook Log endpoint to review past webhook executions.
Supported Events
You can subscribe to the following event types when creating or updating webhooks:
Advocacy Events
| Event Type | Description |
|---|---|
| newAdvocacyMessage | Triggers when a new message is added to the advocacy board |
| newAdvocacyStory | Triggers when a new story is added to the advocacy board |
| newAdvocacyTopic | Triggers when a new topic is added to the advocacy board |
Publishing Events
| Event Type | Description |
|---|---|
| postCreated | Triggers when a user creates a new post |
| postModified | Triggers when a user updates a scheduled post |
| postDeleted | Triggers when a user deletes a scheduled post |
| postSent | Triggers when a post is published to social media, including posts created in the UI |
Engagement Events
| Event Type | Description |
|---|---|
| newInboxItem | Triggers when a new item appears in the inbox |
| newCommentOnInboxItem | Triggers when a new comment or reply is added to an existing Post, Reply, or Mention item |
| newDirectMessageOnInboxItem | Triggers when a new direct message is added to an existing Conversation item |
| inboxItemReplied | Triggers when an Oktopost user sends a reply or direct message from the inbox |
| newNoteOnInboxItem | Triggers when a note is added to an inbox item |
| newInboxItemAssignment | Triggers when an inbox item is assigned to a user |
| inboxItemStatusChange | Triggers when an inbox item is opened or closed |
| inboxItemTagChange | Triggers when tags are added to or removed from an inbox item |
Legacy event types remain supported. Existing subscriptions using newConversation, conversationUpdated, newNoteOnConversation, newAssignment, or conversationStatusUpdated continue to receive events. The legacy newEngagementItem and updatedEngagementItem integrations are also supported.
conversationUpdated is retained only for backward compatibility. For new integrations, subscribe to newCommentOnInboxItem and newDirectMessageOnInboxItem. Reactions and post-content changes do not trigger these customer-facing webhooks.
When a closed inbox item receives a new comment or direct message, Oktopost reopens the item and sends both the applicable content event and inboxItemStatusChange. It does not send newInboxItem because the item already exists.
Lead & Conversion Events
| Event Type | Description |
|---|---|
| newLead | Triggers when a new lead (with an email address) is captured |
| newLeadActivity | Triggers when new social activity is detected for a lead |
| newConversion | Triggers when a social conversion is captured |
Workflow Events
| Event Type | Description |
|---|---|
| newApprovalItem | Triggers when posts or messages are sent to approval |
| approvalItemApproved | Triggers when posts or messages are approved |
| approvalItemRejected | Triggers when posts or messages are rejected |
Other Events
| Event Type | Description |
|---|---|
| newCampaign | Triggers when a new campaign is created |
List Webhooks
Retrieve all webhooks configured in your account with optional filtering and pagination.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| event | String | No | Filter by event type. See supported events above. |
| name | String | No | Search webhooks by name |
| _order | String | No | Sort order. Options: name, description, lastExecutionDate, isEnabled, created, modified. Default: name |
| _page | Integer | No | Page number for pagination. Default: 0 |
| _count | Integer | No | Items per page. Options: 20, 25, 50, 100. Default: 20 |
Request
curl -u ACCOUNT_ID:API_KEY \
"https://api.oktopost.com/v2/webhook"Response
{
"Result": true,
"Items": [
{
"Id": "0WA000000000001",
"Name": "My Webhook",
"Description": "Send new assignment to Slack",
"Event": "newInboxItemAssignment",
"Url": "https://hooks.slack.com/services/...",
"LastExecutionDate": "2024-01-15 10:30:00",
"IsEnabled": 1,
"Created": "2017-05-23 14:07:18",
"Modified": "2017-05-23 14:07:18"
}
],
"Total": 1
}Get Webhook
Retrieve details for a specific webhook by ID.
Request
curl -u ACCOUNT_ID:API_KEY \
https://api.oktopost.com/v2/webhook/0WA000000000001Response
{
"Result": true,
"Webhook": {
"Id": "0WA000000000001",
"Name": "My Webhook",
"Description": "Send new assignment to Slack",
"Event": "newInboxItemAssignment",
"Url": "https://hooks.slack.com/services/...",
"LastExecutionDate": "2024-01-15 10:30:00",
"IsEnabled": 1,
"Created": "2017-05-23 14:07:18",
"Modified": "2017-05-23 14:07:18"
}
}Create Webhook
Create a new webhook to subscribe to a specific event type.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| event | String | Yes | The event type to subscribe to. See supported events above. |
| name | String | Yes | A descriptive name for this webhook |
| url | String | Yes | The endpoint URL where webhook payloads will be sent |
| description | String | No | Additional details about this webhook's purpose |
| isEnabled | Integer | No | Enable or disable the webhook. 1 = enabled, 0 = disabled. Default: 1 |
Request
curl -u ACCOUNT_ID:API_KEY \
https://api.oktopost.com/v2/webhook -X POST \
-d event="newInboxItemAssignment" \
-d name="Slack Assignment Notification" \
-d description="Send assignment notifications to Slack" \
-d url="https://hooks.slack.com/services/..." \
-d isEnabled=1Response
{
"Result": true,
"Webhook": {
"Id": "0WA000000000001",
"Name": "Slack Assignment Notification",
"Description": "Send assignment notifications to Slack",
"Event": "newInboxItemAssignment",
"Url": "https://hooks.slack.com/services/...",
"LastExecutionDate": "-",
"IsEnabled": 1,
"Secret": "a1b2c3d4e5f6...",
"Created": "2017-05-23 14:07:18",
"Modified": "2017-05-23 14:07:18"
}
}When creating a webhook, a Secret is generated. Use this secret to verify that webhook requests are genuinely from Oktopost (see Security section below).
Update Webhook
Modify an existing webhook's configuration.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| event | String | No | Change the event type this webhook subscribes to |
| name | String | No | Update the webhook name |
| url | String | No | Update the destination URL |
| description | String | No | Update the description |
| isEnabled | Integer | No | Enable or disable the webhook. 1 = enabled, 0 = disabled |
Request
curl -u ACCOUNT_ID:API_KEY \
https://api.oktopost.com/v2/webhook/0WA000000000001 -X POST \
-d name="Updated Webhook Name" \
-d description="Updated description" \
-d isEnabled=0Response
{
"Result": true,
"Webhook": {
"Id": "0WA000000000001",
"Name": "Updated Webhook Name",
"Description": "Updated description",
"Event": "newInboxItemAssignment",
"Url": "https://hooks.slack.com/services/...",
"LastExecutionDate": "2024-01-15 10:30:00",
"IsEnabled": 0,
"Created": "2017-05-23 14:07:18",
"Modified": "2024-01-16 09:15:32"
}
}Delete Webhook
Remove a webhook. This action cannot be undone.
Request
curl -u ACCOUNT_ID:API_KEY \
https://api.oktopost.com/v2/webhook/0WA000000000001 -X DELETEResponse
{
"Result": true
}List Webhook Events
Retrieve the non-deprecated webhook event types that can be used when creating a webhook. Authenticate the same way as other webhook endpoints.
Request
curl -u ACCOUNT_ID:API_KEY \
"https://api.oktopost.com/v2/webhook/events"Response
{
"Result": true,
"Events": [
"newAdvocacyMessage",
"postSent",
"newInboxItem",
"newCampaign"
]
}The live array includes every non-deprecated event type, not only the keys shown.
Get Webhook Event
Return a canned sample payload for one event type. The event key is the last path segment. Samples use placeholder IDs and dates; they are not data from your account.
Sample is usually a JSON object; for some events (for example newAdvocacyTopic) it is a JSON array.
Source and Status in the sample below are placeholders (app and sent). On a live postSent delivery, Source and Status use the same values as the Posts API. Live Postlogs contain Id, PostURL, MessageId, and ProfileId only. They do not include RemoteId.
Request
curl -u ACCOUNT_ID:API_KEY \
https://api.oktopost.com/v2/webhook/events/postSentResponse
{
"Result": true,
"Event": "postSent",
"Sample": {
"Id": "pst00000000000000",
"Created": "2026-01-01 12:00:00",
"Modified": "2026-01-01 12:05:00",
"Status": "sent",
"AccountId": "001000000000000",
"CreatedBy": "usr00000000000000",
"ModifiedBy": "usr00000000000000",
"Source": "app",
"ContentSource": "manual",
"Queued": "2026-01-01 11:59:00",
"CampaignId": "002000000000000",
"BoardId": "",
"MessageId": "msg00000000000000",
"MessageChildId": "",
"MessageStatus": "approved",
"Network": "linkedin",
"StartDateTime": "2026-01-01 12:00:00",
"Groups": [],
"GroupsCount": 0,
"TotalCount": 1,
"TargetGeo": "",
"UpdateStatus": "",
"Flag": "",
"Clicks": 0,
"Converts": 0,
"Comments": 0,
"NewComments": 0,
"Likes": 0,
"Utm": "",
"ApproveStatus": "approved",
"Credentials": "cre00000000000000",
"ProfileIds": ["cre00000000000000"],
"Profiles": [
{
"Id": "cre00000000000000",
"Name": "Sample Profile",
"LongName": "Sample Profile (LinkedIn)",
"Type": "company",
"Thumbnail": "https://example.com/thumb.png",
"URL": "https://www.linkedin.com/company/sample"
}
],
"Postlogs": [
{
"Id": "pl000000000000000",
"PostURL": "https://www.linkedin.com/feed/update/urn:li:activity:0",
"MessageId": "msg00000000000000",
"ProfileId": "cre00000000000000"
}
]
}
}Webhook Log
View the execution history for a specific webhook, including response codes, execution times, and payloads sent.
Request
curl -u ACCOUNT_ID:API_KEY \
https://api.oktopost.com/v2/webhook-log/0WA000000000001Response
{
"Result": true,
"Items": [
{
"Id": "0WC000000000001",
"WebhookPayloadId": "0WB000000000001",
"Created": "2017-05-23 14:07:18",
"ResponseCode": 200,
"ExecutionTime": 0.034530,
"Payload": [
{
"Item": {
"Id": "eitm00000000004",
"ItemType": "Post",
"Origin": "external"
},
"Assignee": {
"Id": "00A000000000002",
"Email": "assignee@example.com"
}
}
]
}
],
"Total": 1
}Response Fields
| Field | Description |
|---|---|
| ResponseCode | HTTP status code returned by your webhook endpoint |
| ExecutionTime | Time in seconds it took your endpoint to respond |
| Payload | The complete webhook payload that was sent to your endpoint |
Use webhook logs to:
- Debug webhook delivery issues
- Monitor webhook performance
- Review historical event data
- Verify payload structures
Webhook Payload Structure
When an event occurs, Oktopost sends an HTTP POST to your webhook URL. The body is a JSON array of one or more payload objects. A single action normally produces one element. Payloads that are still waiting to be delivered can be sent together in the same array. Each webhook is subscribed to one event, so every element is that event's payload.
The event name is not in the body. X-Oktopost-Webhook is the webhook id. X-Oktopost-Payload is the payload id, or a comma-separated list when several payloads are sent together.
Inbox events include an inbox item. newInboxItem sends the item as each element of data. The other inbox events nest that same item under Item. ItemType is Conversation, Post, Mention, or Reply, and Data follows that type. See Inbox item Data.
Origin is owned when the activity is from a profile connected to the account, and external otherwise.
For Facebook personal profiles, Origin can be wrong. Facebook uses one profile ID when the profile is connected to Oktopost and a different ID on mentions and comments, so a mention or comment from the connected personal profile can be reported as external.
{
"event": "newAssignment",
"timestamp": 1705315200,
"webhookId": "0WA000000000001",
"data": {
// Event-specific data
}
}newInboxItem
Sent when a new item appears in the inbox.
[
{
"Id": "eitm00000000001",
"Created": "2026-08-04 07:12:59",
"EventDate": "2026-08-04 07:12:52",
"Network": "Facebook",
"ItemType": "Post",
"Status": "open",
"Url": "https://app.oktopost.com/inbox/eitm00000000001",
"Origin": "external",
"Data": {
"PostId": "123456789_987654321",
"PostURL": "https://www.facebook.com/123456789_987654321",
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"CommentProfile": {
"Id": "111222333",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"PostContent": {
"Text": "We're hiring a product designer.",
"Media": []
},
"CommentContent": {
"Text": "Is this role remote?",
"Media": []
},
"CommentDate": "2026-08-04 07:12:52"
}
}
]newCommentOnInboxItem
Sent for a new comment or reply on an existing Post, Reply, or Mention item. The event record contains Item and Text. When an Oktopost user replies from the inbox, use inboxItemReplied instead.
[
{
"Item": {
"Id": "eitm00000000002",
"Created": "2026-08-04 07:12:59",
"EventDate": "2026-08-04 07:48:32",
"Network": "Facebook",
"ItemType": "Post",
"Status": "open",
"Url": "https://app.oktopost.com/inbox/eitm00000000002",
"Origin": "owned",
"Data": {
"PostId": "123456789_987654321",
"PostURL": "https://www.facebook.com/123456789_987654321",
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"CommentProfile": {
"Id": "111222333",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"PostContent": {
"Text": "We're hiring a product designer.",
"Media": []
},
"CommentContent": {
"Text": "A new comment",
"Media": []
},
"CommentDate": "2026-08-04 07:48:32"
}
},
"Text": "A new comment"
}
]newDirectMessageOnInboxItem
Sent for a new direct message on an existing Conversation item. The record contains Item and Text.
[
{
"Item": {
"Id": "eitm00000000003",
"Created": "2026-08-04 11:43:36",
"EventDate": "2026-08-04 11:43:10",
"Network": "Instagram",
"ItemType": "Conversation",
"Status": "open",
"Url": "https://app.oktopost.com/inbox/eitm00000000003",
"Origin": "external",
"Data": {
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"RemoteProfile": {
"Id": "555666777",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"LatestMessage": {
"Text": "A new direct message",
"ProfileId": "0sp000000000001"
},
"PreviousMessage": {
"Text": "Hi, I'd like to learn more.",
"ProfileId": "0sp000000000002"
}
}
},
"Text": "A new direct message"
}
]inboxItemReplied
Sent when an Oktopost user replies or sends a direct message from the inbox. The record contains Item, Author, and Text.
[
{
"Item": {
"Id": "eitm00000000002",
"Created": "2026-08-04 07:12:59",
"EventDate": "2026-08-04 07:48:32",
"Network": "Facebook",
"ItemType": "Post",
"Status": "open",
"Url": "https://app.oktopost.com/inbox/eitm00000000002",
"Origin": "owned",
"Data": {
"PostId": "123456789_987654321",
"PostURL": "https://www.facebook.com/123456789_987654321",
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"CommentProfile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"PostContent": {
"Text": "We're hiring a product designer.",
"Media": []
},
"CommentContent": {
"Text": "Thanks for reaching out — I'll follow up shortly.",
"Media": []
},
"CommentDate": "2026-08-04 07:48:32"
}
},
"Author": {
"Id": "00A000000000001",
"Name": "Alex Rivera",
"Email": "alex.rivera@example.com",
"LastLogin": "2026-08-03 13:25:33"
},
"Text": "Thanks for reaching out — I'll follow up shortly."
}
]newNoteOnInboxItem
The record contains Item, NoteAuthor, and NoteMessage.
[
{
"Item": {
"Id": "eitm00000000004",
"Created": "2026-08-04 07:12:59",
"EventDate": "2026-08-04 07:12:52",
"Network": "Facebook",
"ItemType": "Post",
"Status": "open",
"Url": "https://app.oktopost.com/inbox/eitm00000000004",
"Origin": "external",
"Data": {
"PostId": "123456789_987654321",
"PostURL": "https://www.facebook.com/123456789_987654321",
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"CommentProfile": {
"Id": "111222333",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"PostContent": {
"Text": "We're hiring a product designer.",
"Media": []
},
"CommentContent": {
"Text": "Is this role remote?",
"Media": []
},
"CommentDate": "2026-08-04 07:12:52"
}
},
"NoteAuthor": {
"Id": "00A000000000001",
"Name": "Alex Rivera",
"Email": "alex.rivera@example.com",
"LastLogin": "2026-08-03 13:25:33"
},
"NoteMessage": "Please follow up tomorrow."
}
]newInboxItemAssignment
The record contains Item, Assigner, Assignee, and Note.
[
{
"Item": {
"Id": "eitm00000000004",
"Created": "2026-08-04 07:12:59",
"EventDate": "2026-08-04 07:12:52",
"Network": "Facebook",
"ItemType": "Post",
"Status": "open",
"Url": "https://app.oktopost.com/inbox/eitm00000000004",
"Origin": "external",
"Data": {
"PostId": "123456789_987654321",
"PostURL": "https://www.facebook.com/123456789_987654321",
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"CommentProfile": {
"Id": "111222333",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"PostContent": {
"Text": "We're hiring a product designer.",
"Media": []
},
"CommentContent": {
"Text": "Is this role remote?",
"Media": []
},
"CommentDate": "2026-08-04 07:12:52"
}
},
"Assigner": {
"Id": "00A000000000001",
"Name": "Assigning User",
"Email": "assigner@example.com",
"LastLogin": "2026-08-03 13:25:33"
},
"Assignee": {
"Id": "00A000000000002",
"Name": "Assigned User",
"Email": "assignee@example.com",
"LastLogin": "2026-08-03 10:00:00"
},
"Note": ""
}
]inboxItemStatusChange
The record contains Item, User, and OldStatus. The new status is available in Item.Status.
[
{
"Item": {
"Id": "eitm00000000004",
"Created": "2026-08-04 07:12:59",
"EventDate": "2026-08-04 07:12:52",
"Network": "Facebook",
"ItemType": "Post",
"Status": "closed",
"Url": "https://app.oktopost.com/inbox/eitm00000000004",
"Origin": "external",
"Data": {
"PostId": "123456789_987654321",
"PostURL": "https://www.facebook.com/123456789_987654321",
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"CommentProfile": {
"Id": "111222333",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"PostContent": {
"Text": "We're hiring a product designer.",
"Media": []
},
"CommentContent": {
"Text": "Is this role remote?",
"Media": []
},
"CommentDate": "2026-08-04 07:12:52"
}
},
"User": {
"Id": "00A000000000001",
"Name": "Alex Rivera",
"Email": "alex.rivera@example.com",
"LastLogin": "2026-08-03 13:25:33"
},
"OldStatus": "open"
}
]inboxItemTagChange
The record contains Item, User, OldTags, and NewTags.
[
{
"Item": {
"Id": "eitm00000000004",
"Created": "2026-08-04 07:12:59",
"EventDate": "2026-08-04 07:12:52",
"Network": "Facebook",
"ItemType": "Post",
"Status": "open",
"Url": "https://app.oktopost.com/inbox/eitm00000000004",
"Origin": "external",
"Data": {
"PostId": "123456789_987654321",
"PostURL": "https://www.facebook.com/123456789_987654321",
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"CommentProfile": {
"Id": "111222333",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"PostContent": {
"Text": "We're hiring a product designer.",
"Media": []
},
"CommentContent": {
"Text": "Is this role remote?",
"Media": []
},
"CommentDate": "2026-08-04 07:12:52"
}
},
"User": {
"Id": "00A000000000001",
"Name": "Alex Rivera",
"Email": "alex.rivera@example.com",
"LastLogin": "2026-08-03 13:25:33"
},
"OldTags": [],
"NewTags": [
{
"Id": "etg000000000001",
"Created": "2026-08-02 08:20:05",
"Modified": "2026-08-02 08:20:05",
"InboxId": "ein000000000001",
"Value": "priority"
}
]
}
]Inbox item Data
Data depends on ItemType: Conversation, Post, Mention, or Reply.
Profiles in Data use Id, Name, Picture, and Type. Id is the network profile ID. Type is page, group, or person.
Post text, comments, mentions, and mention replies use Text and a Media array. Media is empty when there are no attachments. Each attachment has Position, Type, URL, LinkTitle, LinkUrl, LinkDescription, Id, ContentId, and PreviewURL. Type is image, gif, video, file, unknown, carousel, or link-image.
Conversation
A direct-message thread. Profile is your connected profile. RemoteProfile is the other person. ProfileId is the sender of that message. Media is included only when the message has attachments. PreviousMessage is [] when there is no earlier message.
{
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"RemoteProfile": {
"Id": "555666777",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"LatestMessage": {
"Text": "A new direct message",
"ProfileId": "0sp000000000001",
"Media": [
{
"Position": 0,
"Type": "image",
"URL": "https://example.com/photo.jpg",
"LinkTitle": null,
"LinkUrl": null,
"LinkDescription": null,
"Id": "12045",
"ContentId": "0ct000000000001",
"PreviewURL": "https://example.com/photo-preview.jpg"
}
]
},
"PreviousMessage": {
"Text": "Hi, I'd like to learn more.",
"ProfileId": "0sp000000000002"
}
}Post
A comment on a post from a connected profile. Profile is your profile. PostContent is the post. CommentProfile is the person who commented. With no comment, CommentProfile and CommentContent are null and CommentDate is "".
{
"PostId": "123456789_987654321",
"PostURL": "https://www.facebook.com/123456789_987654321",
"Profile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"CommentProfile": {
"Id": "111222333",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"PostContent": {
"Text": "We're hiring a product designer.",
"Media": []
},
"CommentContent": {
"Text": "Is this role remote?",
"Media": []
},
"CommentDate": "2026-08-04 07:12:52"
}Mention
Someone mentioned your connected profile. Mention is your profile. MentionedBy is the person who mentioned you. With no reply, Reply is null and ReplyId and ReplyDate are "".
{
"PostURL": "https://twitter.com/555666777/status/987654321",
"Content": {
"Text": "Thanks @acme for the quick help.",
"Media": []
},
"Mention": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"MentionedBy": {
"Id": "555666777",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
},
"Reply": {
"Text": "Glad we could help.",
"Media": []
},
"ReplyId": "1122334455",
"ReplyDate": "2026-08-04 08:01:14"
}Reply
A public reply to a post from a connected profile. SubjectContent is the original post and ReplyContent is the reply. Each has Id and Text only. SubjectProfile is your profile. ReplyProfile is the person who replied.
{
"PostURL": "https://twitter.com/555666777/status/987654321",
"SubjectContent": {
"Id": "987654321",
"Text": "We're hiring a product designer."
},
"ReplyContent": {
"Id": "1122334455",
"Text": "Is this role remote?"
},
"SubjectProfile": {
"Id": "123456789",
"Name": "Acme",
"Picture": "https://example.com/acme.png",
"Type": "page"
},
"ReplyProfile": {
"Id": "555666777",
"Name": "Jordan Lee",
"Picture": "https://example.com/jordan.png",
"Type": "person"
}
}postSent Event:
[
{
"Id": "004000000000001",
"Created": "2024-01-15 10:00:00",
"Modified": "2024-01-15 10:30:00",
"Status": "complete",
"AccountId": "001000000000001",
"CreatedBy": "00A000000000001",
"ModifiedBy": "00A000000000001",
"Source": "UI",
"ContentSource": "User",
"Queued": 0,
"CampaignId": "002000000000001",
"BoardId": "",
"MessageId": "005000000000001",
"MessageChildId": "",
"MessageStatus": "default",
"Network": "Twitter",
"StartDateTime": "2024-01-15 10:30:00",
"Groups": "",
"GroupsCount": 0,
"TotalCount": 1,
"TargetGeo": "",
"UpdateStatus": 1,
"Flag": "",
"Clicks": 0,
"Converts": 0,
"Comments": 0,
"NewComments": 0,
"Likes": 0,
"Utm": "",
"ApproveStatus": "approved",
"Credentials": "003-001000000000001-12345678",
"ProfileIds": ["003-001000000000001-12345678"],
"Profiles": [
{
"Id": "003-001000000000001-12345678",
"Name": "Oktopost",
"LongName": "Oktopost (X)",
"Type": "personal",
"Thumbnail": "https://example.com/thumb.png",
"URL": "https://x.com/Oktopost"
}
],
"Postlogs": [
{
"Id": "007000000000001",
"PostURL": "https://x.com/Oktopost/status/xxxx",
"MessageId": "005000000000001",
"ProfileId": "003-001000000000001-12345678"
}
]
}
]postSent Postlogs do not include RemoteId. Read that id from the Post Log.
newLeadActivity Event:
[
{
"Id": "act000000000001",
"ContactId": "0ld000000000001",
"ActivityDate": "2024-01-15 10:30:00",
"AccountId": "001000000000001",
"Type": "comment",
"Network": "LinkedIn",
"ProfileId": "003-001000000000001-123456",
"PostlogId": "007000000000000",
"Data": {}
}
]approvalItemApproved Event:
[
{
"WorkflowItemID": "004000000000001",
"StoryID": "0ST000000000001",
"BoardID": "0BD000000000001",
"PostId": null,
"MessageId": null,
"Network": "LinkedIn",
"WorkflowId": "cwf000000000001",
"ApprovedBy": "00A000000000001",
"ApprovedAt": "2024-01-15 10:30:00"
}
]Approval webhook payloads (newApprovalItem, approvalItemApproved, approvalItemRejected) include WorkflowItemID, StoryID, and BoardID fields. The entity is resolved in order: StoryID → PostId → MessageId (only one will be populated).
When available, inbox item payloads include a Language field containing an automatically detected ISO 639-1 language code, such as en, fr, or es. When language detection is unavailable, the field is null.
Security Best Practices
Verify Webhook Signatures
Check X-Oktopost-Secret before you trust a delivery. It proves the request came from Oktopost and that the body was not changed in transit.
Each request includes three headers:
| Header | Value |
|---|---|
X-Oktopost-Secret | The signature. Compare this with the value you calculate below. |
X-Oktopost-Webhook | The id of the webhook that sent the request. |
X-Oktopost-Payload | The id of this delivery. When the body contains more than one payload, the ids are separated by commas. |
Calculate the signature from the request body and the Secret returned when the webhook was created:
- Read the body as text, exactly as it arrived, before you parse it as JSON.
- Compute HMAC-SHA1 of that text, using the webhook
Secretas the key. - Encode the result as hexadecimal.
- Compare it with the
X-Oktopost-Secretheader. Accept the request only when they match.
Parse the JSON only after the check succeeds. If you parse the body and turn it back into a string, spacing or key order can change, and the signature will not match.
const crypto = require('crypto');
// rawBody: the POST body as text, before JSON.parse
// signature: the X-Oktopost-Secret header
// secret: the Secret returned when the webhook was created
function verifyWebhook(rawBody, signature, secret) {
const expectedSignature = crypto
.createHmac('sha1', secret)
.update(rawBody)
.digest('hex');
return signature === expectedSignature;
}Endpoint Requirements
Your webhook endpoint should:
- Respond quickly - Return a 2xx status code within 5 seconds
- Use HTTPS - All webhook URLs must use HTTPS
- Handle retries - Oktopost retries failed webhooks up to 3 times
- Be idempotent - Handle duplicate webhook deliveries gracefully
- Check the signature - Compare
X-Oktopost-Secretwith your calculated signature before processing the body
Error Handling
If your endpoint returns a non-2xx status code or times out:
- Oktopost will retry the webhook up to 3 times
- Retries use exponential backoff (5s, 25s, 125s)
- After 3 failed attempts, the webhook delivery is abandoned
- Check the webhook log to diagnose delivery issues
Common Use Cases
Slack Notifications
Send real-time alerts to Slack when conversations are assigned or posts are published.
CRM Integration
Automatically create or update CRM records when new leads or conversions are captured.
Custom Analytics
Stream event data to your analytics platform for custom reporting and dashboards.
Workflow Automation
Trigger automated workflows in tools like Zapier, Make, or n8n based on Oktopost events.
Audit Logging
Maintain a complete audit trail of all activities in an external database.
Getting Started
To start using webhooks:
- Set up an endpoint - Create a publicly accessible HTTPS endpoint to receive webhooks
- Create a webhook - Use the API to create a webhook pointing to your endpoint
- Test the webhook - Trigger the subscribed event in Oktopost to test delivery
- Verify signatures - Implement signature verification for security
- Handle errors - Add error handling and logging to your webhook handler
- Monitor logs - Use the webhook log endpoint to monitor delivery and troubleshoot issues
For questions or assistance with webhook implementation, please contact our support team.