Developer docs

ViewTracker Publishing API

Publish and schedule social posts with a Postiz-compatible API contract. Includes migration instructions, platform settings and OpenAPI.

Create drafts, enqueue posts, schedule publication and inspect each destination using the same connections, content checks and background publisher as the ViewTracker app.

Base URL: https://www.viewtracker.ai/api/public/v1

Download OpenAPI 3.1 for Postman or client generation. The tracking API and webhooks are separate.

Authentication and access

Connect accounts in Publish → Profiles & accounts and create a workspace API key in Settings. Raw-key Authorization matches Postiz. Bearer authentication also works.

bash
export VIEWTRACKER_BASE_URL='https://www.viewtracker.ai/api/public/v1'
export VIEWTRACKER_API_KEY='vt_live_REPLACE_ME'
curl "$VIEWTRACKER_BASE_URL/integrations" \
  -H "Authorization: $VIEWTRACKER_API_KEY"

Keys belong to one workspace and cover all its publishing profiles; per-profile key scopes are unavailable. Keep them on your server. Revocation stops authenticated calls, but does not cancel scheduled posts. Reading requires Growth or higher; uploads, publication and cancellation require Ultra or higher and an active subscription. Publishing must also be enabled for the workspace. API access does not bypass provider app review, account authorization or the current rollout gate.

The shared limit is 120 requests per minute per key, including tracking and MCP calls. Throttled responses include Retry-After. Authenticated responses are not cached.

Migrate from Postiz

This implements the documented publishing subset, rather than the entire Postiz API.

  1. 1Connect the same social accounts to ViewTracker through the app. OAuth grants and tokens are not imported from Postiz.
  2. 2Create a ViewTracker API key and change the client's base URL and key.
  3. 3Fetch GET /integrations and update stored integration IDs. Profile/group, media and post IDs are service-specific too.
  4. 4Upload media to ViewTracker and use the returned media IDs.
  5. 5Check the platform settings and compatibility table below, then test your automation.
text
Before: https://api.postiz.com/public/v1
After:  https://www.viewtracker.ai/api/public/v1
Authorization: <ViewTracker API key>

A client that discovers channels and uploads media dynamically can keep the supported paths and JSON structure after this setup. Hard-coded Postiz IDs must change. Existing schedules remain in Postiz: changing a URL does not move or cancel them. Check or cancel the original before recreating a pending post to avoid publishing twice.

Checked against the official Postiz API reference and create-post schema on November 3, 2026. SDKs and n8n nodes that use unsupported endpoints, settings or Postiz OAuth tokens need changes; full interchangeability is not claimed.

Endpoints

All paths below are relative to the Publishing base URL.

MethodPathResult
GET/is-connected{ "connected": true } after key, plan and Publishing checks
GET/meorganization { id, name }, user: null
GET/groupsActive publishing profiles as { id, name }
GET/integrationsAuthorized accounts; optional group profile filter
GET/integration-settings/{id}output.rules, maxLength, settings and tools: []
GET/postsDestinations within required startDate and endDate; optional customer profile filter
POST/postsDraft, immediate or scheduled posts
DELETE/posts/{id}Cancel an unstarted group; retain history
DELETE/posts/group/{group}Same cancellation using the listed group ID
POST/uploadOne multipart file, up to 4 MiB
POST/upload-from-urlImport public HTTPS media
GET/media/{id}/statusVerify file availability; return ready
GET/mediapages and results, 18 files per page
POST/uploads/presignViewTracker extension: signed direct-upload PUT
POST/uploads/completeViewTracker extension: verify and register the PUT

An integration is a publishing destination, not a tracked analytics account. Facebook destinations are Pages. Instagram reports instagram-standalone; settings accept either instagram-standalone or instagram. Discovery never exposes social tokens.

One account can belong to several profiles. customer is the filtered or earliest active profile, and the groups extension lists all active memberships. The optional profileId on each post item selects one; otherwise the earliest active profile containing that account is used.

Create a post and first comment

The first value item is the root. A second item creates one text-only first comment or Threads reply, when the account's existing permission grant allows it. No new permission is requested through this endpoint. YouTube first comments are unavailable.

bash
curl -X POST "$VIEWTRACKER_BASE_URL/posts" \
  -H "Authorization: $VIEWTRACKER_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: release-2026-11-03-threads-1" \
  -d '{
    "type": "now", "shortLink": false, "tags": [],
    "posts": [{
      "integration": { "id": "pcn_FROM_INTEGRATIONS" },
      "value": [
        { "content": "Our new release is here.", "image": [] },
        { "content": "More at https://example.com/release", "image": [] }
      ],
      "settings": { "__type": "threads" }
    }]
  }'
json
[{ "postId": "ptg_EXAMPLE", "integration": "pcn_FROM_INTEGRATIONS" }]

Acceptance means queued, not published. The background worker normally begins within a minute; provider media processing can take longer. Use GET /posts to inspect outcomes. A first comment has its own result; its failure does not undo a successful root post.

Drafts, scheduling and idempotency

type now ignores date and queues immediately. type draft stores without publishing. type schedule requires date in ISO 8601 with an explicit UTC offset, at least one minute ahead and within 60 days. Each item may have different content, media and settings. Up to 12 items share the request intent/date and commit atomically; a failed validation or final write creates none of them.

Send a unique Idempotency-Key for each intended batch. Retrying the same parsed payload returns the same destination IDs, including after publication. Reusing it with changed content returns 409. JSON object-key ordering does not matter; post ordering does. An edit to the original post can also return 409 and should be inspected. Without this header, repeating POST creates another batch.

Use shortLink: false and tags: [], or omit them. Link shortening, top-level tagging, recurring intervals, supplied group IDs, editing through nested post IDs and arbitrary reply chains are unavailable. Unknown fields fail validation. Content is plain text; rich-text HTML is not converted.

Media uploads

JPEG/PNG images: up to 8 MiB. MP4/MOV videos: up to 500 MiB. Instagram requires JPEG images; PNG is not converted automatically. Media must meet the destination's encoding, duration, dimensions and aspect-ratio rules.

For a file up to 4 MiB:

bash
curl -X POST "$VIEWTRACKER_BASE_URL/upload" \
  -H "Authorization: $VIEWTRACKER_API_KEY" \
  -F 'file=@photo.jpg' -F 'adjust=false'

For a larger file on a public server:

bash
curl -X POST "$VIEWTRACKER_BASE_URL/upload-from-url" \
  -H "Authorization: $VIEWTRACKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/original.mp4","adjust":false}'

The source must provide HTTPS, a supported Content-Type and positive Content-Length. Private, loopback, internal and metadata addresses are blocked, including redirect targets. The API key is never forwarded to the source. Imports are streamed with byte and time bounds. adjust=true and automatic transcoding are unsupported.

For authenticated sources, chunked downloads or local large files:

  1. 1POST /uploads/presign with name, size in bytes and type. Example: { "name": "clip.mp4", "size": 10485760, "type": "video/mp4" }.
  2. 2PUT the bytes to the returned url with the returned headers. Do not send your ViewTracker API key to storage.
  3. 3POST /uploads/complete with { "id": "ID_FROM_PRESIGN" }.
  4. 4Use the returned id and path in the root item's image array, including for video.
json
{
  "integration": { "id": "pcn_INSTAGRAM" },
  "value": [{
    "content": "A look at our new release.",
    "image": [{ "id": "pmd_EXAMPLE.jpg", "path": "URL_FROM_UPLOAD" }]
  }],
  "settings": { "__type": "instagram-standalone", "post_type": "post" }
}

An upload response includes id, name, path, organizationId, createdAt, updatedAt and status ready. id is the authoritative ViewTracker reference; path is a preview URL valid for one hour. It is not fetched from the caller when posting. Scheduling generates fresh delivery links at execution. Old Postiz media IDs cannot be reused.

Files are temporary publishing assets. Unattached uploads are protected for at least seven days. Drafts and pending posts protect referenced files, subject to the bucket's 90-day lifecycle. After all destinations finish, normal cleanup uses the seven-day retry window. Scheduling verifies enough media lifetime remains. This is not permanent archival storage.

GET /media?page=1 returns pages and results. Names use storage IDs; original-name search is unavailable. GET /media/{id}/status checks actual object availability. Missing or expired media must be uploaded again.

Platform settings and formats

Match settings.__type to the authorized account. Unsupported choices return 422 before scheduling.

PlatformSettingsFormats
Facebook__type: facebook; optional title for videoText, photo, image carousel, video, Reel, Story
Instagram__type: instagram or instagram-standalone; post_type: post, reel or story; optional share_to_feedJPEG photo, supported carousel, video/Reel, Story
Threads__type: threadsText, photo, supported carousel, video
YouTube__type: youtube; title; type: private, unlisted or publicOne video
TikTok__type: tiktok; content_posting_method: UPLOAD; optional titleOne video delivered to Inbox

YouTube also accepts selfDeclaredMadeForKids: yes/no and tags [{ value, label? }], at most 30 tags and 450 combined characters including separators.

Format is inferred: no media → text, one image → photo, several files → carousel, one Instagram video → reel, other single videos → video. The optional format extension explicitly selects text, photo, carousel, video, reel or story. Use format: reel for a Facebook Reel. Normal platform/format checks still apply, including carousel limitations.

Instagram is_trial_reel may be false and collaborators may be empty. Trial Reels, collaborators, alt text, cover-frame/music selection, custom thumbnails, delayed comments and Facebook link-preview/background settings are unavailable.

TikTok Direct Post requires the composer's interactive creator choices and consent; this API exposes only UPLOAD. Inbox delivery is not public publication. Privacy, duet, stitch, comment, music and disclosure settings have no effect in UPLOAD mode and are finalized in TikTok, matching Postiz's Inbox behavior.

Instagram and Facebook Stories

Use settings.post_type: story for Facebook or Instagram, or the format: story extension. One image or video creates one Story; upload a finished file with any desired text already embedded. Root content must be empty, and first comments are unavailable. Captions are rejected rather than silently omitted. The editor has the same Story format and supports drafts and schedules.

The ViewTracker limits are one file, videos up to 100 MB and 3–60 seconds, Facebook images up to 4 MiB, and Instagram JPEG images up to 8 MiB. The editor checks available duration metadata; Meta validates the actual media encoding and duration. A vertical 9:16 canvas is recommended. Story eligibility depends on Meta and the connected professional account; some Instagram login/account configurations require a Business account.

Stories expire on the social platform after 24 hours. They are retained in ViewTracker history with their publication result, but do not enter video tracking. Meta may not return a usable permalink; a missing link is not an error after a confirmed publication. Music, polls, link stickers and other interactive overlays are not added automatically. Prepare overlays in your media or add them natively.

json
{
  "type": "schedule",
  "date": "2026-11-10T10:00:00Z",
  "posts": [{
    "integration": { "id": "pcn_INSTAGRAM" },
    "value": [{ "content": "", "image": [{ "id": "pmd_EXAMPLE.jpg", "path": "URL_FROM_UPLOAD" }] }],
    "settings": { "__type": "instagram-standalone", "post_type": "story" }
  }]
}

History and cancellation

GET /posts requires startDate and endDate, at most 93 days apart. customer filters by publishing profile. More than 1000 matching destinations returns 422; split the date range rather than assuming partial results are complete.

bash
curl "$VIEWTRACKER_BASE_URL/posts?startDate=2026-11-01T00:00:00Z&endDate=2026-11-30T23:59:59Z" \
  -H "Authorization: $VIEWTRACKER_API_KEY"

The posts array has one entry per destination: id, group, content, publishDate, releaseURL, releaseId, integration, image, settings, state and error. ViewTracker adds the precise status and separate firstComment result. Compatibility states are DRAFT, QUEUE, PUBLISHED and ERROR. TikTok Inbox delivery has terminal status in_drafts and compatibility state QUEUE because it is not publicly published; do not wait for a public URL. A failed comment appears separately even when the root is PUBLISHED.

DELETE uses the returned destination postId, or group from listing. Both paths cancel all unstarted destinations in the parent post. Canceled entries disappear from API lists but remain in app history. Repeating cancellation is safe. Processing, published, failed or remotely initialized posts return 409. No published content is deleted from the social network.

Compatibility boundaries

Postiz featureViewTracker
Raw-key AuthorizationSupported with a ViewTracker key; Bearer also accepted
Integrations and groupsSupported; groups map to publishing profiles
now, draft, schedule, per-channel contentSupported for the five platforms above
One first comment/replySupported where the existing account grant permits it
Multipart uploadSame path/form; 4 MiB limit here
URL uploadSame path/JSON; supported MIME and Content-Length required
Media adjustment or name searchUnavailable
DeleteCancels unstarted delivery, preserves history, no remote deletion
TikTok Direct PostInteractive composer only
OAuth apps, channel-connect API, provider toolsUnavailable; connect in the app
Slot discovery, status/settings updates, release-ID repairUnavailable; use the editor and queue
Postiz analytics/notificationsUnavailable; ViewTracker tracking API is separate
Other platforms, AI generation and clippingUnavailable in this Publishing API

Recognized unimplemented Postiz endpoint families return 501; unknown paths return 404. Migration does not change any provider's app-review status.

Errors and retry behavior

Errors are JSON { "error": "message" }, with a docs link for Publishing-specific failures.

StatusMeaning
400Invalid JSON, unknown fields or malformed request
401Missing, invalid or revoked ViewTracker key
402Inactive subscription
403Plan or Publishing rollout does not permit access
404Resource not found in this workspace, or unknown path
409Idempotency conflict, edited post or publication started
413Body or file exceeds its limit
422Unsupported settings or failed content, date or media checks
429Shared key rate limit; observe Retry-After
501Recognized Postiz endpoint is not implemented
502/503Temporary upstream storage, database or service failure

JSON bodies are limited to 512 KiB. Retry transient failures with backoff and the same Idempotency-Key for post creation. Do not create another post just because a response was lost. Asynchronous provider failures appear in destination history after acceptance.