Skip to main content
Understanding responses, error handling, and status codes for every Partner API endpoint. Designed for easy parsing by OpenClaw agents, Claude Code, and any programmatic integration.

Envelope Structure

All endpoints return the same typed envelope so you can branch on ok once and stay type-safe everywhere else.
ok
boolean
required
Indicates success (true) or failure (false).
code
number
required
Mirrors the HTTP status code returned by the endpoint.
message
string
required
Human-readable context for logs or UI surfaces.
data
object
Present only when ok is true. Contains the payload documented for each endpoint.
error_code
string
Optional machine-friendly identifier for failures (e.g., invalid_token, subscription_required).
{
  "ok": true,
  "code": 200,
  "message": "Accounts retrieved",
  "data": { "...": "..." }
}
{
  "ok": false,
  "code": 401,
  "message": "API key not found",
  "error_code": "invalid_token"
}
When ok is true, data is guaranteed to exist. When ok is false, data is omitted, so you can rely on that distinction for strict typing in TypeScript, Swift, or Go clients.

Sample Handling

const res = await fetch("https://www.genviral.io/api/partner/v1/accounts", {
  headers: { Authorization: `Bearer ${process.env.GENVIRAL_TOKEN}` },
});
const payload = await res.json();

if (!payload.ok) {
  throw new Error(`Genviral error ${payload.code}${payload.message}`);
}

payload.data.accounts.forEach((account: any) => {
  console.log(account.id, account.type, account.platform);
});
response = requests.get(
    "https://www.genviral.io/api/partner/v1/posts",
    headers={"Authorization": f"Bearer {GENVIRAL_TOKEN}"}
)
data = response.json()

if data["ok"]:
    print(data["data"]["summary"])
else:
    raise RuntimeError(f"Genviral error {data['code']}: {data['message']}")

Common Status Codes

CodeMeaningNotes
200SuccessReturned for GET/PATCH requests and POST /posts/retry.
201CreatedReturned by create-style endpoints such as POST /posts, POST /slideshows/generate, POST /packs, POST /packs/:pack_id/images, POST /templates, POST /templates/from-slideshow/:slideshow_id, and POST /slideshows/:slideshow_id/duplicate.
202AcceptedReturned for async-start endpoints such as POST /studio/videos/generate.
400Bad RequestMissing/invalid parameters, unreachable media URLs, etc.
401UnauthorizedAPI key missing, malformed, or revoked.
402Subscription RequiredActive Creator, Professional, or Business subscription is required.
403ForbiddenTier or scope denied (e.g., tier_not_allowed for Scheduler).
404Not FoundResource doesn’t exist in the authenticated key scope.
422Unprocessable EntityJSON body parsed but failed schema validation (invalid payload).
429Too Many RequestsBack off-respect concurrency guidance (3–10 requests at a time).
500Internal Server ErrorRare; retry with exponential backoff and contact support if needed.
error_code is the fastest way to branch on known issues (e.g., invalid_media_url, post_not_mutable). Log both code and error_code for observability.

Handling 422 invalid_payload

When payload validation fails, Partner API returns 422 with field-level details.
{
  "ok": false,
  "code": 422,
  "message": "Invalid payload",
  "error_code": "invalid_payload",
  "issues": {
    "fieldErrors": {
      "caption": ["String must contain at most 500 character(s)"],
      "accounts": ["Expected object, received string"]
    }
  }
}
Recommended handling:
  1. Detect code === 422 and error_code === "invalid_payload".
  2. Read issues.fieldErrors.
  3. Fix field shape/data and retry.
  4. Do not retry unchanged payloads.
if (!payload.ok && payload.code === 422 && payload.error_code === "invalid_payload") {
  const fieldErrors = payload.issues?.fieldErrors ?? {};
  console.error("Invalid payload", fieldErrors);
  throw new Error("Fix payload shape before retrying");
}