API Guide

REST architecture, JSON-only responses, Bearer token auth. Every endpoint lives under /api/v1 and returns the same response envelope.

Your first request in four steps

There is no separate developer screen: your API identity is your own account.

  1. Open your account
    The email and password you use in the panel are also your API credentials. You do not need to generate a separate key.
  2. Get a token
    POST your credentials to the signin endpoint; the response field data.token is your session token.
  3. Add it to the header
    Carry the token on every following request in the Authorization: Bearer header. No cookies are sent.
  4. Read the envelope
    Look at the result field in the body, not just the HTTP status: on ok you read data, on error you read error.code.

Code samples

The address below is derived from the domain this page is served from — you can copy it as is.

curl1 — Requesting a token
curl -X POST 'https://sosyalasistan.app/api/v1/signin' \
  -H 'Content-Type: application/json' \
  -d '{"mail": "[email protected]", "password": "your-password"}'
json2 — Successful response
{
  "result": "ok",
  "data": {
    "token": "7f1c…",
    "user": { "id": "7312904418291712", "mail": "[email protected]" }
  }
}
curl3 — Authenticated request with the token
curl 'https://sosyalasistan.app/api/v1/me' \
  -H 'Authorization: Bearer 7f1c…'
json4 — Error response
{
  "result": "error",
  "error": { "code": "UNAUTHENTICATED", "message": "Oturum yok" }
}

Tokens live in Redis and are invalidated on sign-out; the signout endpoint accepts POST or DELETE.

Endpoint directory

Every live resource and the credential each one needs. The list is locked against the routing registry; only the router internals and one provider callback stay out.

Endpoint Identity
Identity and session Token creation, sign-out, and the session owner's own record.
/api/v1/signin no auth
/api/v1/signout Bearer token
/api/v1/me Bearer token
Account and team Users, companies, sub-users, and permissions.
/api/v1/users admin permission
/api/v1/companies Bearer token
/api/v1/subUsers Bearer token
/api/v1/permissions Bearer token
/api/v1/companyImages Bearer token
Social publishing Connected channels, posts, workflows, feeds, and reports.
/api/v1/channels Bearer token
/api/v1/posts Bearer token
/api/v1/workflows Bearer token
/api/v1/feeds Bearer token
/api/v1/analytics admin permission
Blog and content Blog posts, topics, personas, automation, and the knowledge base.
/api/v1/blog no auth write: admin permission
/api/v1/blogTopics admin permission
/api/v1/blogPersonas admin permission
/api/v1/blogAutomation admin permission
/api/v1/blogReact no auth
/api/v1/blogSubscribe callback
/api/v1/blogTrending no auth
/api/v1/knowledge no auth
AI and files Generation requests, the assistant, and uploaded files.
/api/v1/ai Bearer token
/api/v1/aiCopilot Bearer token
/api/v1/files Bearer token
System and notifications Health checks, metrics, the audit log, notifications, and webhooks.
/api/v1/health no auth
/api/v1/metrics operations credential
/api/v1/audit admin permission
/api/v1/notifications Bearer token
/api/v1/webhooks callback
/api/v1/onboarding Bearer token
/api/v1/support Bearer token
/api/v1/sales Bearer token write: admin permission
/api/v1/publishApproval callback

The verb mapping is the same for every resource: GET to list and read, POST to create, PUT to update, DELETE to remove. The response tells you which verbs a resource supports — an unsupported verb returns 405.

no auth
No header required; the request works as-is.
Bearer token
Send the data.token value from the POST /api/v1/signin response in the Authorization: Bearer … header.
admin permission
Requires an administrative identity and permission; a customer token does not pass — depending on the endpoint you get 401 or 403.
operations credential
Requires a separate monitoring credential (an X-Metrics-Token header or an allow-listed IP); a customer token does not pass, and with no configuration it returns 401.
callback
You are not the caller: the request is authenticated by the provider signature or by a single-use link sent in e-mail.

The envelope is the same for every resource: a successful response carries result: "ok" plus data, an error carries result: "error" plus error.code. Field lists are printed further down this page for the resources listed there; for the rest, the response to your own request is the authority on field names.

Error codes

error.code is always present in an error body. Branch on the codes you recognise and fall back to the HTTP status class for everything else: an endpoint may answer with a code that is more specific than the generic set below.

Status Error code Meaning
400 INVALID_INPUT The input format is invalid.
401 UNAUTHENTICATED The token is missing, invalid, or expired.
403 FORBIDDEN The identity is valid but you are not authorized for this record.
404 NOT_FOUND The resource was not found.
409 ALREADY_EXISTS The record already exists or the state conflicts.
422 VALIDATION_FAILED Field validation failed; the detail is in error.fields.
429 RATE_LIMITED The request limit was exceeded; wait before retrying.
500 INTERNAL_ERROR An unexpected error on the server side.

Endpoint-specific codes

These rows are not hand-written either: the code is read from the file that actually emits it and the status from the same map the server uses. Your very first request can already return a code that is not in the table above.

Endpoint Status Error code Meaning
/api/v1/signin 401 INVALID_CREDENTIALS The e-mail and password did not match — sign-in answers with this code, not with UNAUTHENTICATED.
/api/v1/publishApproval 400 TOKEN_REQUIRED The approval-link token is missing. This code is not in the status map, so it falls back to the default status.

The table above is the generic set, not the whole list: 413 codes are mapped to a status in our code and further codes are produced without a mapping — an unmapped code comes back with the default 400. Handle a code you do not recognise by its HTTP status class, and never read a status as if it implied the generic code.

Example request bodies

These field lists are not hand-written: they are read from the validation group that filters the endpoint's own requests, so what the gate enforces is what you see.

/api/v1/signin rule group: signin

Field Required Rules
mail yes email
password yes string
google_authenticator no max:24

/api/v1/companies rule group: create

Field Required Rules
title no max:160
mail no email max:255
phone no phone max:30
address no max:500
country no max:64
timezone no max:64
logo no max:2048
color no max:32
whatsapp_number no phone max:30
sector no max:120
size no max:32
website_url no max:2048
website no max:2048
category_slug no max:120
name no max:160

/api/v1/companies rule group: update

Field Required Rules
title no max:160
mail no email max:255
phone no phone max:30
address no max:500
country no max:64
timezone no max:64
logo no max:2048
color no max:32
whatsapp_number no phone max:30
sector no max:120
size no max:32
website_url no max:2048
website no max:2048
category_slug no max:120

/api/v1/posts rule group: create

Field Required Rules
description no min:1 max:20000
company_id no objectid
workflow_id no objectid
assign_id no objectid
format no string max:16
content_type no string max:16
media_urls no string max:8000
video_asset_id no objectid
video_ai_generated no boolean
style_brief_id no objectid
client_token no string min:16 max:64
platform_texts no string max:500000
platform_media no string max:40000
first_comment no string max:20000
internal_title no string max:100
internal_labels no string max:4000
platform_settings no string max:4000

/api/v1/posts rule group: update

Field Required Rules
description no max:20000
company_id no objectid
workflow_id no objectid
assign_id no objectid
platform_texts no string max:500000
platform_media no string max:40000
first_comment no string max:20000
internal_title no string max:100
internal_labels no string max:4000
platform_settings no string max:4000

Three resources are listed here for now; the field list for the remaining 30 has not been written yet. Rules appear in the validator's own notation: max:255 means at most 255 characters, in:a,b means only the listed values.

Verifying webhooks

Every delivery we send to your endpoint is signed. The headers below are printed from the constants in our code, not typed by hand.

Header Sample value
X-Sosyalasistan-Signature v1=8f3c…
X-Sosyalasistan-Timestamp 1758412800
X-Sosyalasistan-Event order.created
X-Sosyalasistan-Delivery 901f2b…
textThe signed base string — timestamp, dot, raw body
1758412800.{"event":"order.created",…}

Verify like this: build the base string, compute HMAC-SHA256 with your subscription secret, prefix the lowercase hex with v1=, and compare in constant time. The timestamp sits inside the signature, so you can drop a stale delivery with your own abs(now − timestamp) threshold.

Frequently asked questions

  • How does versioning work?
    The version travels in the address. Every API response returns the X-Min-Version and X-Latest-Version headers; today both are 1.
  • Which header should carry the token?
    The preferred form is Authorization: Bearer <token>. The server also accepts the X-Auth-Token header. External integrations should not rely on cookies; always send the token in a header.
  • How are list endpoints paginated?
    With the page and per_page query parameters; per_page defaults to 20 and is capped at 100. The page information comes back in the meta.pagination field.
  • Why do record IDs come back as strings?
    IDs are 64-bit integers and JavaScript loses precision at that width. They are therefore returned as strings in JSON; compare them as strings.
  • What format do date fields use?
    Every date field is a unix epoch integer in seconds. No textual date format is returned.
  • Is the response always JSON?
    Yes — every response, error paths included, is served with the application/json header. If you get HTML back, the request never reached the API; check the version prefix in the address.