Docs
Posts
POST
/posts/validate

Takes the same body as creating a post and runs every check (text length and media per platform, accounts, schedule, queue) without storing anything. Answers 200 with valid: false and the problems instead of an error, so agents can fix everything in one round.

Requires posts:read.

Authorization

bearerAuth
AuthorizationBearer <token>

API key starting with fh_

In: header

Header Parameters

Idempotency-Key?string

Any unique string up to 255 characters. A retry with the same key within 24 hours returns the first response instead of running again.

Lengthlength <= 255

Request Body

application/json

profileId*string

Profile id

Match^prof_[0-9a-fA-F]{32}$
content?string

Post text. Each account can get its own text through targets

Lengthlength <= 63206
platforms?array<>

Publish to every active account of these platforms in the profile

Items1 <= items
accountIds?array<>

Or name the accounts explicitly (wins over platforms)

Items1 <= items
targets?array<>

The accounts to publish to, each with optional own text. Wins over platforms and accountIds

Items1 <= items <= 50
mediaIds?array<>

Files from POST /media, in display order

Itemsitems <= 20
scheduledFor?string

Schedule for this time. Leave out all three timing fields for a draft

Formatdate-time
publishNow?boolean

Publish right away

addToQueue?boolean

Take the profile's next free queue slot

timezone?string

Time zone shown with the post. Defaults to the profile's

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://feedhorizon.com/api/v1/posts/validate" \  -H "Content-Type: application/json" \  -d '{    "profileId": "prof_0195f0a27b3c7d4e8f5a1b2c3d4e5f60"  }'
{
  "data": {
    "valid": true,
    "errors": [
      {
        "code": "string",
        "message": "string",
        "param": "string",
        "accountId": "acc_0195f0a27b3c7d4e8f5a1b2c3d4e5f60",
        "platform": "twitter"
      }
    ],
    "warnings": [
      {
        "code": "string",
        "message": "string",
        "param": "string",
        "accountId": "acc_0195f0a27b3c7d4e8f5a1b2c3d4e5f60",
        "platform": "twitter"
      }
    ],
    "scheduledAt": "2026-11-10T08:00:00.000Z",
    "targets": [
      {
        "accountId": "acc_0195f0a27b3c7d4e8f5a1b2c3d4e5f60",
        "platform": "twitter"
      }
    ]
  }
}
{
  "error": {
    "type": "invalid_request_error",
    "code": "invalid_json",
    "message": "The body is not valid JSON",
    "docUrl": "https://feedhorizon.com/docs/api/errors#invalid_request_error",
    "requestId": "req_m2x81a0kfd3h9s"
  }
}
{
  "error": {
    "type": "authentication_error",
    "code": "missing_api_key",
    "message": "No Authorization: Bearer header",
    "docUrl": "https://feedhorizon.com/docs/api/errors#authentication_error",
    "requestId": "req_m2x81a0kfd3h9s"
  }
}
{
  "error": {
    "type": "permission_error",
    "code": "insufficient_scope",
    "message": "The key lacks the scope for this endpoint",
    "docUrl": "https://feedhorizon.com/docs/api/errors#permission_error",
    "requestId": "req_m2x81a0kfd3h9s"
  }
}
{
  "error": {
    "type": "idempotency_error",
    "code": "idempotency_request_in_progress",
    "message": "The first request with this key is still running. Retry in a few seconds",
    "docUrl": "https://feedhorizon.com/docs/api/errors#idempotency_error",
    "requestId": "req_m2x81a0kfd3h9s"
  }
}
{
  "error": {
    "type": "idempotency_error",
    "code": "idempotency_key_reused",
    "message": "The key was used for a different request. Use a new key",
    "docUrl": "https://feedhorizon.com/docs/api/errors#idempotency_error",
    "requestId": "req_m2x81a0kfd3h9s"
  }
}
{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limited",
    "message": "Too many requests. Wait the seconds in Retry-After",
    "docUrl": "https://feedhorizon.com/docs/api/errors#rate_limit_error",
    "requestId": "req_m2x81a0kfd3h9s"
  }
}
{
  "error": {
    "type": "api_error",
    "code": "internal_error",
    "message": "Something failed on our side. Retry with backoff, using the same Idempotency-Key for writes",
    "docUrl": "https://feedhorizon.com/docs/api/errors#api_error",
    "requestId": "req_m2x81a0kfd3h9s"
  }
}