openapi: 3.1.0 info: title: Undress API description: API for undressing images, face swaps, and animations. Premium v3 lives under its own `/api/v3/undress` namespace; everything else is served from `/api/v1/...`. version: 2.0.0 contact: name: DeepStrip url: https://deepstrip.com/ servers: - url: https://deepstrip.com components: securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: API key description: "Opaque API key issued at /api/documentation. Sent as `Authorization: Bearer `." schemas: UndressRequest: type: object required: - style properties: source_image: type: string description: Base64 encoded source image in jpeg, png, or webp format (max 12 MB). Required unless `parent` is supplied. mask: type: string description: "Base64 encoded mask image in png format (max 1 MB). Contains two colors: white for undressing regions, black for the rest. Only honored when style is `premium_v2` and `automask` is not `true`; ignored for all other styles." automask: type: boolean description: When `true`, the server generates the mask. Only meaningful for `premium_v2`; `standard` and `video` always auto-mask server-side regardless of this field. parent: type: string description: ID of a previous `video` Undress to continue with the next clothing layer. Style and source are inherited; the parent must be less than 24 hours old. style: type: string description: The model for undressing. `premium_v3` is served from a dedicated endpoint (`POST /api/v3/undress`) and is not accepted here. enum: [standard, premium_v2, video] body_shape: type: string description: Body shape adjustment (only for premium_v2 style). enum: ["null", fat, skinny, athletic, old] boobs: type: string description: Breast size adjustment (only for premium_v2 style). enum: ["null", small, large] hair: type: string description: Pubic hair style (only for premium_v2 style). enum: ["null", hairy, shaved] UndressV3Request: type: object required: - image_url - person_id properties: image_url: type: string format: uri description: HTTPS URL of the source image (jpeg, png, or webp, max 12 MB). The same URL the caller submitted to `POST /api/v1/persons/analyze`. person_id: type: string description: Identifier returned by `GET /api/v1/persons/analyze/{id}` for the specific person to undress. Must belong to an analysis of the same `image_url`, owned by the caller, and still within the 3-hour cache window. person_gender: type: string description: Override the detector's gender for this person. Use when the detector misclassifies and you want to force the opposite workflow. Case-insensitive. When omitted, the detector's gender is used. enum: [male, female] PersonsAnalyzeRequest: type: object required: - image_url properties: image_url: type: string format: uri description: HTTPS URL of the image to analyze. The detector service fetches it directly. PersonsAnalyzeResponse: type: object properties: id: type: string description: Identifier for the analysis job. Poll with `GET /api/v1/persons/analyze/{id}`. PersonSchema: type: object properties: id: type: string description: Stable identifier for this person within the analysis result. Pass as `person_id` to `POST /api/v3/undress`. bbox: type: array description: Bounding box in source-image pixel coordinates, `[x1, y1, x2, y2]`. items: type: number minItems: 4 maxItems: 4 age: type: number description: Estimated age. Persons without a recognized age are not returned. gender: type: string description: Detected gender. Persons without a recognized gender are not returned. enum: [male, female] score: type: number description: Detector confidence for the person box. PersonsAnalysisStatusResponse: type: object properties: status: type: string enum: [pending, completed, failed] persons: type: array description: Only present when `status` is `completed`. May be an empty array when the detector finds no recognized persons in the image. items: $ref: "#/components/schemas/PersonSchema" details: type: string description: Failure reason. Only present when `status` is `failed`. enum: [detector_failed] FaceSwapRequest: type: object required: - image - face properties: image: type: string description: Base64 encoded image. face: type: string description: Base64 encoded face image. version: type: string description: Version of the face swap model. enum: [v1, v2] mode: type: string description: Swap type. `face_swap` (default, 3 credits) replaces only the face; `head_swap` (5 credits) replaces the entire head. enum: [face_swap, head_swap] default: face_swap UndressResponse: type: object properties: id: type: string description: Identifier for the job. FaceSwapResponse: type: object properties: id: type: string description: Identifier for the job. ErrorResponse: type: object properties: error: type: string errors: type: array items: type: string UndressResultResponse: type: object properties: status: type: string description: Status of the undress job. enum: [pending, completed, failed] image: type: string description: URL of the generated image, if the job is completed. DEPRECATED — use `result`. result: type: string description: URL of the generated result, if the job is completed. For `video` style this is an mp4 URL; otherwise an image URL. details: type: string description: Failure reason. Only present when `status` is `failed`. enum: [analysis_failed, system_error] FaceSwapResultResponse: type: object properties: status: type: string description: Status of the face swap job. enum: [pending, completed, failed] image: type: string description: URL of the generated image, if the job is completed. FaceSwapVideoAnalyzeRequest: type: object required: - video_url properties: video_url: type: string description: HTTPS URL of the video to analyze. preview: type: boolean description: Whether to create a preview (shorter) version. version: type: string description: Version of the face swap model. enum: [v1, v2] FaceSwapVideoAnalyzeResponse: type: object properties: price: type: number description: Calculated price for the face swap video, in credits. duration: type: integer description: Detected video duration in seconds. FaceSwapVideoRequest: type: object properties: video_url: type: string description: HTTPS URL of the video to process. face_url: type: string description: HTTPS URL of the face image. preview: type: boolean description: Whether to create a preview version. version: type: string description: Version of the face swap model. enum: [v1, v2] FaceSwapVideoResponse: type: object properties: id: type: string description: Identifier for the face swap video job. status: type: string description: Initial status of the job. message: type: string description: Additional information about the job. FaceSwapVideoStatusResponse: type: object properties: id: type: string description: Identifier for the face swap video job. status: type: string description: Status of the face swap video job. enum: [initial, sent, processing, completed, failed] progress: type: number description: Progress percentage of the processing. step: type: string description: Current processing step. enum: [queued, downloading, fps, analysing, working, sound, reencoding_step_1, reencoding_step_2, postprocessing, uploading] result_url: type: string description: URL of the processed video, if completed. error_details: type: object description: Error information if the job failed. created_at: type: string format: date-time description: When the job was created. updated_at: type: string format: date-time description: When the job was last updated. AnimationRequest: type: object properties: source_image: type: string description: Base64 encoded data URI in jpeg, png, or webp format (e.g., data:image/jpeg;base64,/9j/4AAQ...). Required unless `parent_id` is supplied; ignored when `parent_id` is supplied (the parent's last video frame is always used as input). template_id: type: integer description: ID of the animation template to use. Get available templates from /animation_templates endpoint. Combo templates cost 14 credits instead of 7. Optional when `parent_id` is supplied (defaults to the parent's template; pass a different one to switch styles); otherwise required. quality: type: string description: "Output quality. `sd` (default) renders up to 480x640; `hd` renders up to 720x1280 (source aspect ratio preserved) and costs 2x the template price (see `price_hd` in `/api/v1/animation_templates`). Omit for backward-compatible SD. Inherited from the parent and ignored when `parent_id` is supplied." enum: [sd, hd] default: sd preset_id: type: integer description: "Deprecated: use template_id instead. ID of the animation template." parent_id: type: string description: ID of a previous Animation to continue. The new clip is concatenated to the parent's video. The parent's last video frame is always used as the source (any `source_image` is ignored). `template_id` is optional and defaults to the parent's template. Parent must be less than 24 hours old and have a saved last frame. undress_before_animation: type: boolean description: "When `true`, the photo is first undressed (Premium v3, 3 credits, charged separately; an internal step, hidden from the undress history on the website) and the animation runs on the undressed result. Only honored for templates whose `undress_before_animation` flag is `true` (see `/api/v1/animation_templates`), and only on a fresh animation (ignored when `parent_id` is supplied). Requires `image_url` + `person_id` instead of `source_image` — see the Persons Analysis API." image_url: type: string format: uri description: "Required when `undress_before_animation` is `true`. HTTPS URL of the source image (jpeg, png, or webp, max 12 MB) — the same URL submitted to `POST /api/v1/persons/analyze`. Replaces `source_image` for the undress-before-animation flow; `source_image` is ignored when `image_url`/`person_id` are present." person_id: type: string description: "Required when `undress_before_animation` is `true`. Identifier of the person to undress, taken from a `completed` `GET /api/v1/persons/analyze/{id}` result owned by the caller and still within the 3-hour cache window. Must belong to an analysis of the same `image_url`." person_gender: type: string description: "Override the detector's gender for the undressed person. Only used in the undress-before-animation flow. Case-insensitive." enum: [male, female] body_shape: type: string description: "Body figure for the undress step (female persons only). Only used in the undress-before-animation flow. `as_in_photo` lets the AI keep what it sees." enum: [as_in_photo, fat, skinny, athletic] boobs: type: string description: "Breast size for the undress step (female persons only). Only used in the undress-before-animation flow. `as_in_photo` lets the AI decide." enum: [as_in_photo, small, large, huge] AnimationResponse: type: object properties: id: type: string description: Identifier for the animation job. AnimationResultResponse: type: object properties: status: type: string description: Status of the animation job. enum: [pending, completed, failed] result: type: string description: URL of the generated video, if the job is completed. error_details: type: object description: Error information when the animation failed due to image analysis. Only present when status is "failed" and the failure was caused by content analysis (underage person detected). properties: code: type: string description: Error code indicating the failure reason. enum: [face.child] underage_persons: type: array description: Detected underage persons with age and bounding box coordinates. Only present when code is "face.child". items: type: object properties: age: type: number description: Estimated age of the detected person. face: type: object description: Bounding box coordinates of the detected face. properties: x1: type: integer x2: type: integer y1: type: integer y2: type: integer body: type: object description: Bounding box coordinates of the detected body. properties: x1: type: integer x2: type: integer y1: type: integer y2: type: integer AnimationTemplateListResponse: type: array items: type: object properties: id: type: integer description: Template ID to use with the animation API. name: type: string description: English name of the template. name_de: type: string description: German name (falls back to English if not set). name_es: type: string description: Spanish name (falls back to English if not set). name_pt: type: string description: Portuguese name (falls back to English if not set). name_fr: type: string description: French name (falls back to English if not set). name_ru: type: string description: Russian name (falls back to English if not set). name_zh: type: string description: Chinese name (falls back to English if not set). combo: type: boolean description: Whether this is a combo template (combines two templates). price: type: integer description: SD credit cost for this template (7 for standard, 14 for combo). price_hd: type: integer description: HD credit cost for this template (2x `price`; 14 for standard, 28 for combo). undress_before_animation: type: boolean description: "Whether this template supports the optional \"undress before animation\" step. When `true`, you may pass `undress_before_animation: true` (with `image_url` + `person_id`) to `POST /api/v1/animations`." UndressFaceSwapVideoRequest: type: object required: - undress_id properties: undress_id: type: string description: ID of a completed `video`-style Undress owned by the caller. UndressFaceSwapVideoResponse: type: object properties: id: type: string description: Identifier of the UndressFaceSwapVideo record. face_swap_video_id: type: string description: Identifier of the underlying face swap video job; poll `/face_swap_videos/{id}` for processing status. undress_id: type: string description: Identifier of the source video-style Undress. undress_result_id: type: string nullable: true description: Identifier of the resulting Undress once the face swap completes. `null` while processing. security: - bearerAuth: [] paths: /api/v1/undress: post: summary: Create an undress job operationId: createUndress requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UndressRequest" responses: "200": description: Job created successfully. content: application/json: schema: $ref: "#/components/schemas/UndressResponse" "400": description: Invalid parameters, no credits, expired parent, or too many retries. content: application/json: schema: type: object properties: error: type: string enum: [no_credits, invalid_params, too_many_retries, parent_expired, internal_server_error] errors: type: array description: Validation error messages. Only present when `error` is `invalid_params`. items: type: string /api/v1/persons/analyze: post: summary: Queue a person-detection analysis for an image URL description: "Detects persons on the image at `image_url` and returns an analysis id. Rate limited to 15 requests per minute per API key. Results are cached for 3 hours. Poll `GET /api/v1/persons/analyze/{id}` for the outcome." operationId: createPersonsAnalysis requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PersonsAnalyzeRequest" responses: "201": description: Analysis queued. content: application/json: schema: $ref: "#/components/schemas/PersonsAnalyzeResponse" "400": description: "Invalid parameters (missing `image_url`, non-HTTPS URL, or malformed URL)." content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "429": description: Rate limit exceeded (more than 15 analyses per minute for this API key). content: application/json: schema: type: object properties: error: type: string example: rate_limited retry_after: type: integer description: Seconds until the next minute window, after which new requests will succeed. /api/v1/persons/analyze/{id}: get: summary: Get a persons-analysis result description: "Returns `pending` while the detector is running, `completed` with the persons list when done, or `failed` with a `details` code. A `completed` response with an empty `persons` array means the image had no recognized persons (not a failure). Returns 404 after the 3-hour cache TTL expires or if the id was not created by the caller." operationId: getPersonsAnalysis parameters: - name: id in: path required: true schema: type: string description: Analysis id returned by `POST /api/v1/persons/analyze`. responses: "200": description: Current status of the analysis. content: application/json: schema: $ref: "#/components/schemas/PersonsAnalysisStatusResponse" "404": description: Analysis not found, expired, or not owned by the caller. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v3/undress: post: summary: Create a premium v3 undress job (explicit person selection) description: "Premium v3 — 5 credits, always auto-masks, always requires an explicit person selected via `POST /api/v1/persons/analyze`. Pass back the exact `image_url` you analyzed plus the `person_id` from the analysis result." operationId: createUndressV3 requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UndressV3Request" responses: "201": description: Job created successfully. content: application/json: schema: $ref: "#/components/schemas/UndressResponse" "400": description: "Invalid parameters, invalid/expired/foreign person_id, image URL unreachable, underage subject, or insufficient credits." content: application/json: schema: type: object properties: error: type: string enum: [invalid_params, invalid_person_id, image_fetch_failed, under_age, no_credits] errors: type: array description: Validation error messages. Only present when `error` is `invalid_params`. items: type: string /api/v3/undress/{id}: get: summary: Get the result of a premium v3 undress job operationId: getUndressV3Result parameters: - name: id in: path required: true schema: type: string description: Identifier of the undress job. responses: "200": description: Status or result of the undress job (same shape as `GET /api/v1/undress/{id}`). content: application/json: schema: $ref: "#/components/schemas/UndressResultResponse" "404": description: Job not found. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v3/undress/{id}/regenerate: post: summary: Regenerate a premium v3 undress for free (once per parent, 24 hours) description: "Creates a new premium v3 undress using the same source image and selected person as the parent, with a different random seed. Completely free — no credits are charged. Exactly one free regeneration is allowed per parent. The parent must be a completed premium v3 undress less than 24 hours old. Poll the returned id via `GET /api/v3/undress/{id}`." operationId: regenerateUndressV3 parameters: - name: id in: path required: true schema: type: string description: Identifier of the parent premium v3 undress. responses: "201": description: Regeneration job created successfully. content: application/json: schema: $ref: "#/components/schemas/UndressResponse" "400": description: Regeneration not available for this parent. content: application/json: schema: type: object properties: error: type: string enum: [already_regenerated, parent_expired, parent_not_completed, not_v3, invalid_params] "404": description: Parent not found, or created by a different API key. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/face_swap_videos/analyze: post: summary: Analyze a video for face swap processing operationId: analyzeFaceSwapVideo requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/FaceSwapVideoAnalyzeRequest" responses: "200": description: Analysis completed successfully. content: application/json: schema: $ref: "#/components/schemas/FaceSwapVideoAnalyzeResponse" "400": description: Invalid parameters or URL. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Analysis failed due to video constraints. content: application/json: schema: type: object properties: error: type: string example: "ANALYSIS_FAILED" details: type: string example: "too_large" "500": description: Internal server error. /api/v1/face_swap_videos: post: summary: Create a face swap video job operationId: createFaceSwapVideo requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/FaceSwapVideoRequest" multipart/form-data: schema: $ref: "#/components/schemas/FaceSwapVideoRequest" responses: "201": description: Job created successfully. content: application/json: schema: $ref: "#/components/schemas/FaceSwapVideoResponse" "400": description: Invalid parameters, files, or URLs. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Internal server error. /api/v1/face_swap_videos/{id}: get: summary: Get the status of a face swap video job operationId: getFaceSwapVideoStatus parameters: - name: id in: path required: true schema: type: string description: Identifier of the face swap video job. responses: "200": description: Current status of the face swap video job. content: application/json: schema: $ref: "#/components/schemas/FaceSwapVideoStatusResponse" "404": description: Job not found. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Internal server error. /api/v1/undress/{id}: get: summary: Get the result of an undress job operationId: getUndressResult parameters: - name: id in: path required: true schema: type: string description: Identifier of the undress job. responses: "200": description: Status or result of the undress job. content: application/json: schema: $ref: "#/components/schemas/UndressResultResponse" "404": description: Job not found. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/undress_face_swap_videos: post: summary: Run a free face swap over a completed video-style undress description: Applies only to completed `video`-style Undresses. Improves face consistency in the animated result; typically completes in 60–120 seconds. Poll `/undress_face_swap_videos/{id}` for status, then fetch the resulting video via `/undress/{undress_result_id}`. operationId: createUndressFaceSwapVideo requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UndressFaceSwapVideoRequest" responses: "200": description: Job created successfully. content: application/json: schema: $ref: "#/components/schemas/UndressFaceSwapVideoResponse" "404": description: Undress not found, not owned by the caller, or not a `video`-style undress. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "422": description: Service failed to enqueue the face swap job. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/undress_face_swap_videos/{id}: get: summary: Get the status of an undress face swap video job operationId: getUndressFaceSwapVideo parameters: - name: id in: path required: true schema: type: string description: Identifier of the UndressFaceSwapVideo record. responses: "200": description: While processing, `undress_result_id` is `null`. Once populated, fetch the swapped result via `/undress/{undress_result_id}`. content: application/json: schema: $ref: "#/components/schemas/UndressFaceSwapVideoResponse" "404": description: Record not found or not owned by the caller. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/face_swaps: post: summary: Create a face swap job operationId: createFaceSwap requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/FaceSwapRequest" responses: "200": description: Job created successfully. content: application/json: schema: $ref: "#/components/schemas/FaceSwapResponse" "400": description: Invalid parameters or no credits. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" "500": description: Internal server error. /api/v1/face_swaps/{id}: get: summary: Get the result of a face swap job operationId: getFaceSwapResult parameters: - name: id in: path required: true schema: type: string description: Identifier of the face swap job. responses: "200": description: Status or result of the face swap job. content: application/json: schema: $ref: "#/components/schemas/FaceSwapResultResponse" "404": description: Job not found. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/animations: post: summary: Create an animation job operationId: createAnimation requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/AnimationRequest" responses: "200": description: Job created successfully. content: application/json: schema: $ref: "#/components/schemas/AnimationResponse" "400": description: "Invalid parameters, no credits, expired parent, analysis failed (child detected, no face found), or (undress-before-animation only) invalid person, image fetch failure, or underage subject." content: application/json: schema: type: object properties: error: type: string enum: [invalid_params, no_credits, analysis_failed, parent_expired, internal_server_error, invalid_person_id, image_fetch_failed, under_age] errors: type: array items: type: string error_details: type: object description: Analysis failure details. Only present when error is "analysis_failed". properties: code: type: string enum: [face.child] underage_persons: type: array description: Detected underage persons. Only present when code is "face.child". items: type: object properties: age: type: number face: type: object properties: x1: type: integer x2: type: integer y1: type: integer y2: type: integer body: type: object properties: x1: type: integer x2: type: integer y1: type: integer y2: type: integer /api/v1/animations/{id}: get: summary: Get the result of an animation job operationId: getAnimationResult parameters: - name: id in: path required: true schema: type: string description: Identifier of the animation job. responses: "200": description: Status or result of the animation job. content: application/json: schema: $ref: "#/components/schemas/AnimationResultResponse" "404": description: Job not found. content: application/json: schema: $ref: "#/components/schemas/ErrorResponse" /api/v1/animation_templates: get: summary: List available animation templates operationId: listAnimationTemplates security: [] responses: "200": description: List of available animation templates. content: application/json: schema: $ref: "#/components/schemas/AnimationTemplateListResponse" /api/v1/animation_presets: get: summary: "Deprecated: use /api/v1/animation_templates instead" operationId: listAnimationPresets deprecated: true security: [] responses: "200": description: List of available animation templates (deprecated endpoint). content: application/json: schema: $ref: "#/components/schemas/AnimationTemplateListResponse"