mangaPoser
Register
REST API · v1

API Reference

Base URL: https://mangaposer.cc/api/v1  ·  All endpoints return JSON  ·  CORS enabled

Quick Start

1

Register

Create an account at mangaposer.cc/register

2

Get API Key

Go to Account → API Keys → Generate New Key

3

Call the API

Pass your key as Authorization: Bearer mp_...

Authentication
Authorization: Bearer mp_your_api_key_here

Poses

GET /api/v1/poses Auth required

Query Parameters

q string Full-text search against pose slug and tags
tag string Filter by exact tag label (e.g. `combat`)
sort string `quality` (default) | `community` | `newest` | `most_used`
limit integer Results per page (default 50, max 200)
offset integer Pagination offset (default 0)

Example

curl
curl "https://mangaposer.cc/api/v1/poses?tag=combat&sort=quality&limit=10" \
  -H "Authorization: Bearer mp_your_token"

Response

application/json
{
  "poses": [
    {
      "pose_slug": "combat_punch_r",
      "title": "Combat Punch R",
      "thumbnail_url": "/thumbnails/combat_punch_r.webp",
      "tags": ["combat", "attack", "punch"],
      "quality_score": 4,
      "community_score": 1.5,
      "feedback_count": 12,
      "license_type": "CC0",
      "submitted_by": 3,
      "submitted_by_name": "Alice"
    }
  ],
  "total": 51,
  "limit": 50,
  "offset": 0,
  "has_more": true
}
POST /api/v1/poses Auth required

Request Body (JSON)

pose_slug string required Unique identifier. Lowercase, alphanumeric, `_` or `-`
bone_data_url string required URL to bone data JSON (glTF Humanoid quaternions)
thumbnail_url string optional URL to WebP thumbnail (default: `/thumbnails/{slug}.webp`)
source_url string optional Original source reference URL
license_type string optional License identifier (default `CC0`)
quality_score integer optional Expert quality rating 1–5 (default 3)
tags string[] optional Array of tag labels to attach

Example

curl
curl -X POST "https://mangaposer.cc/api/v1/poses" \
  -H "Authorization: Bearer mp_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "pose_slug": "my_custom_pose",
    "bone_data_url": "https://example.com/bones/my_custom_pose.json",
    "quality_score": 3,
    "tags": ["standing", "gesture"]
  }'

Response

application/json
{
  "ok": true,
  "pose": { /* PoseDetail object */ }
}
GET /api/v1/poses/{slug} Auth required

Example

curl
curl "https://mangaposer.cc/api/v1/poses/sword_slash" \
  -H "Authorization: Bearer mp_your_token"

Response

application/json
{
  "pose_slug": "sword_slash",
  "title": "Sword Slash",
  "thumbnail_url": "/thumbnails/sword_slash.webp",
  "bone_data_url": "/poses/bones/sword_slash.json",
  "tags": ["combat", "sword", "attack", "dynamic"],
  "quality_score": 3,
  "community_score": 0.0,
  "feedback_count": 0,
  "license_type": "CC0",
  "source_url": "https://github.com/una-dinosauria/cmu-mocap",
  "submitted_by": 3,
  "submitted_by_name": "Alice"
}
PATCH /api/v1/poses/{slug} Auth required

Request Body (JSON)

bone_data_url string optional New bone data URL
thumbnail_url string optional New thumbnail URL
quality_score integer optional 1–5
tags string[] optional Replaces all existing tags

Example

curl
curl -X PATCH "https://mangaposer.cc/api/v1/poses/my_custom_pose" \
  -H "Authorization: Bearer mp_your_token" \
  -H "Content-Type: application/json" \
  -d '{"quality_score": 4, "tags": ["standing", "gesture", "emotion"]}'

Response

application/json
{ "ok": true, "pose": { /* PoseDetail */ } }
DELETE /api/v1/poses/{slug} Auth required

Example

curl
curl -X DELETE "https://mangaposer.cc/api/v1/poses/my_custom_pose" \
  -H "Authorization: Bearer mp_your_token"

Response

application/json
{ "ok": true }

Semantic Search

POST /api/v1/recommend Auth required

Request Body (JSON)

description string required Natural language scene description. Keywords are matched against tags.

Example

curl
curl -X POST "https://mangaposer.cc/api/v1/recommend" \
  -H "Authorization: Bearer mp_your_token" \
  -H "Content-Type: application/json" \
  -d '{"description": "character lunging forward sword raised"}'

Response

application/json
{
  "recommendations": [
    {
      "pose_slug": "sword_slash",
      "thumbnail_url": "/thumbnails/sword_slash.webp",
      "quality_score": 3,
      "community_score": 0.0,
      "matched_tags": ["combat", "sword"],
      "match_score": 2
    }
  ]
}

Community Feedback

POST /api/v1/feedback No auth

Request Body (JSON)

pose_slug string required Target pose slug
rating string required `great` | `good` | `bad` | `terrible` | `fix_needed`
comment string optional Required when `rating = fix_needed`
turnstile_token string required Cloudflare Turnstile challenge token
session_token string required Client session identifier (16–32 hex chars). One rating per session per pose.

Example

curl
curl -X POST "https://mangaposer.cc/api/v1/feedback" \
  -H "Content-Type: application/json" \
  -d '{
    "pose_slug": "combat_punch_r",
    "rating": "great",
    "turnstile_token": "<challenge_token>",
    "session_token": "abc123def456..."
  }'

Response

application/json
{ "ok": true }

Error Codes

400 Bad Request Missing or invalid parameters
401 Unauthorized Missing, invalid, or revoked API key
404 Not Found The requested resource does not exist
409 Conflict A resource with that slug already exists
500 Server Error Unexpected server-side error
All error responses include an error string field:
{ "error": "Description of the problem" }

Rate Limits

free 1,000 req / day Default for all new API keys
standard 10,000 req / day Contact us to upgrade
premium Unlimited Enterprise / research partnerships

Rate limits are keyed per API key (not IP). Exceeded limits return HTTP 429.

Bone Data Format

Bone data is stored as glTF Humanoid rotation quaternions per bone, relative to bind pose. 55 standard bones: Hips, Spine, Chest, UpperChest, Neck, Head, plus Left/Right Shoulder/UpperArm/LowerArm/Hand/Fingers/UpperLeg/LowerLeg/Foot/Toes.

bone_data.json
{
  "hips":         { "x": 0.0,    "y": 0.0,    "z": 0.0,    "w": 1.0 },
  "spine":        { "x": 0.052,  "y": 0.0,    "z": 0.0,    "w": 0.999 },
  "chest":        { "x": 0.035,  "y": 0.0,    "z": 0.0,    "w": 0.999 },
  "leftUpperArm": { "x": 0.0,    "y": 0.0,    "z": 0.383,  "w": 0.924 },
  "rightUpperArm":{ "x": 0.0,    "y": 0.0,    "z": -0.383, "w": 0.924 },
  ...
}