{"status": "ok"} for initial testingPOST https://{YOUR-HOST}/{ENDPOINT}
Required: Provide both production and sandbox URLs during setup.
| Header | Type | Description |
|---|---|---|
Content-Type |
Required | application/json |
Authorization |
Required | Bearer {API_TOKEN} |
X-Signature |
Optional | HMAC-SHA256 signature for payload verification |
{
"fieldData": {
"name": "Post Title",
"slug": "converted-post-title",
"published_date": "2025-07-04T10:30:00Z",
"content": "<p>Post HTML content</p>",
"description": "Post summary",
"image": {
"url": "https://example.com/image.jpg"
},
"alttags": "keyword1, keyword2, keyword3, keyword4, keyword5",
"category": "Bitcoin | Ethereum | Altcoins | AI",
"read_time": 5
}
}
| Field | Type | Required | Description | SEO Enhancement |
|---|---|---|---|---|
| name | string | Yes | Title (max 200) | Recommend 50–60 chars for Google |
| slug | string | Yes | URL slug | Lowercase, hyphens, ≤ 60 chars |
| published_date | string | Yes | ISO timestamp | Add updated_date optional |
| content | string (HTML) | Yes | HTML content | Must include heading structure |
| description | string | Yes | Meta excerpt | 140–160 optimal for SERP preview |
| image.url | string | Yes | HTTPS image | ≥1200×630 px, <150KB |
| image.alt | string | Optional | Image description | Required for accessibility & SEO |
| seo_keywords | string | Yes | 5–6 keywords | Replace misleading alttags label |
| primary_category | string | Yes | Top category | e.g. “Bitcoin” |
| tags[] | string[] | Optional | Related topics | e.g. [“Layer 2”, “Argentina”] |
| read_time | int | Yes | Minutes | Add word_count (optional) |
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "ok",
"post_id": 123
}
| Status Code | Description | Retry Policy | Common Causes |
|---|---|---|---|
400 |
Bad Request - Validation failed | No | Invalid field formats, missing required fields |
401 |
Unauthorized - Invalid token | No | Expired/invalid API token |
403 |
Forbidden - Access denied | No | IP not allowlisted, invalid signature |
429 |
Too Many Requests | Yes, after 30s | Rate limit exceeded (30 req/min) |
500 |
Internal Server Error | Yes | Temporary server issues |
503 |
Service Unavailable | Yes | Maintenance mode |
Include your API token in every request:
Authorization: Bearer your-api-token-here
Security Notes:
Restrict webhook delivery to specific IP ranges. Contact support to configure your allowlist.
Benefits: Additional firewall-level protection Considerations: Ensure all your server IPs are included
Innerly signs each payload using HMAC-SHA256. Verify signatures to ensure payload integrity.
Python:
import hmac
import hashlib
import json
def verify_signature(payload_body, signature_header, secret):
expected_signature = hmac.new(
secret.encode('utf-8'),
payload_body.encode('utf-8'),
hashlib.sha256
).hexdigest()
# Signature format: "sha256=<hash>"
provided_signature = signature_header.replace('sha256=', '')
return hmac.compare_digest(expected_signature, provided_signature)
# Usage in your webhook handler
def webhook_handler(request):
payload = request.body
signature = request.headers.get('X-Signature', '')
if not verify_signature(payload, signature, YOUR_WEBHOOK_SECRET):
return {"error": "Invalid signature"}, 401
# Process the webhook...
return {"status": "ok"}
Node.js:
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
const providedSignature = signature.replace('sha256=', '');
return crypto.timingSafeEqual(
Buffer.from(expectedSignature, 'hex'),
Buffer.from(providedSignature, 'hex')
);
}
PHP:
function verifySignature($payload, $signature, $secret) {
$expectedSignature = hash_hmac('sha256', $payload, $secret);
$providedSignature = str_replace('sha256=', '', $signature);
return hash_equals($expectedSignature, $providedSignature);
}
import time
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_session_with_retries():
session = requests.Session()
retry_strategy = Retry(
total=3,
status_forcelist=[429, 500, 502, 503, 504],
method_whitelist=["HEAD", "GET", "POST"],
backoff_factor=1
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("http://", adapter)
session.mount("https://", adapter)
return session
Cause: Invalid payload format Solution:
Cause: Invalid or missing API token Solution:
Cause: IP allowlisting or signature verification failure Solution:
Use these payloads to test your webhook implementation:
{
"fieldData": {
"name": "Test Article",
"slug": "test-article",
"published_date": "2025-07-04T12:00:00Z",
"content": "<p>This is a test article content.</p>",
"description": "Test article description",
"image": { "url": "https://example.com/test-image.jpg" },
"alttags": "test, article, sample, demo, innerly",
"category": "Bitcoin",
"read_time": 3
}
}
Basic webhook simulation:
curl -X POST 'https://your-webhook-url.com/webhook' -H 'Authorization: Bearer YOUR_API_TOKEN' -H 'Content-Type: application/json' -d '{
"fieldData": {
"name": "Test Article",
"slug": "test-article",
"published_date": "2025-07-04T12:00:00Z",
"content": "<p>Test content</p>",
"description": "Test description",
"image": {"url": "https://example.com/image.jpg"},
"alttags": "test, webhook, api",
"category": "Bitcoin",
"read_time": 2
}
}'
Testing with signature:
# Generate signature first, then:
curl -X POST 'https://your-webhook-url.com/webhook' -H 'Authorization: Bearer YOUR_API_TOKEN' -H 'Content-Type: application/json' -H 'X-Signature: sha256=YOUR_CALCULATED_SIGNATURE' -d @test-payload.json