{
  "openapi": "3.0.3",
  "info": {
    "title": "OpusImg Public API",
    "version": "0.1.0",
    "description": "The public HTTP API for OpusImg: synchronous image compression and conversion, queued background removal, job polling, and webhook management. Authenticate with a Bearer API key created in the OpusImg dashboard. This document covers the public surface only."
  },
  "servers": [
    {
      "url": "https://api.opusimg.com",
      "description": "Production"
    }
  ],
  "externalDocs": {
    "description": "Developer documentation",
    "url": "https://opusimg.com/developers"
  },
  "tags": [
    {
      "name": "Public API v1"
    },
    {
      "name": "Webhooks"
    }
  ],
  "paths": {
    "/v1/compress": {
      "post": {
        "summary": "Compress an image",
        "tags": [
          "Public API v1"
        ],
        "description": "Re-encode an image at a lower quality, optionally changing format at the same time. Synchronous: the compressed bytes come back in the response body.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "image"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "binary",
                    "description": "The source image. JPEG, PNG, WebP or AVIF, 20 MB maximum."
                  },
                  "quality": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 80,
                    "description": "Encoder quality. 75-85 is the usual range."
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "jpeg",
                      "png",
                      "webp",
                      "avif"
                    ],
                    "description": "Output format. Defaults to the input format."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "The transformed image bytes, with a Content-Type of image/*.",
            "content": {
              "image/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "No API key, or a key that is invalid, expired or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The key's plan or scopes do not permit this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The input image is larger than 20 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "The request is missing an image, or a parameter is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly operation cap exceeded. See Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/convert": {
      "post": {
        "summary": "Convert an image to another format",
        "tags": [
          "Public API v1"
        ],
        "description": "Re-encode an image into a different format. Synchronous: the converted bytes come back in the response body.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "image",
                  "format"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "binary",
                    "description": "The source image. JPEG, PNG, WebP or AVIF, 20 MB maximum."
                  },
                  "format": {
                    "type": "string",
                    "enum": [
                      "jpeg",
                      "png",
                      "webp",
                      "avif"
                    ],
                    "description": "Required. The format to convert to."
                  },
                  "quality": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 80,
                    "description": "Encoder quality. 75-85 is the usual range."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "The transformed image bytes, with a Content-Type of image/*.",
            "content": {
              "image/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "No API key, or a key that is invalid, expired or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The key's plan or scopes do not permit this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The input image is larger than 20 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "The request is missing an image, or a parameter is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly operation cap exceeded. See Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/remove-background": {
      "post": {
        "summary": "Remove an image background",
        "tags": [
          "Public API v1"
        ],
        "description": "Queue an AI background removal. Asynchronous: returns 202 with a job id immediately, then poll GET /v1/jobs/{id} until status is done.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "image"
                ],
                "properties": {
                  "image": {
                    "type": "string",
                    "format": "binary",
                    "description": "The source image. JPEG, PNG, WebP or AVIF, 20 MB maximum."
                  },
                  "background": {
                    "type": "string",
                    "default": "transparent",
                    "description": "transparent, or a CSS colour to composite the cut-out onto."
                  },
                  "refine_edges": {
                    "type": "boolean",
                    "default": true,
                    "description": "Run the edge refinement pass."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "The job was queued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Job id. Poll GET /v1/jobs/{id}."
                    },
                    "status": {
                      "type": "string",
                      "description": "queued, running, done or failed."
                    },
                    "status_url": {
                      "type": "string",
                      "description": "Relative URL to poll."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No API key, or a key that is invalid, expired or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The key's plan or scopes do not permit this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The input image is larger than 20 MB.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "The request is missing an image, or a parameter is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or monthly operation cap exceeded. See Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "summary": "Get the status of a job",
        "tags": [
          "Public API v1"
        ],
        "description": "Poll a queued job. Once status is done the response carries a short-lived presigned download_url for the output. Polling does not count toward the monthly operation cap.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The job id returned when the job was queued."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "The current state of the job.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "description": "queued, running, done or failed."
                    },
                    "progress": {
                      "type": "number",
                      "description": "0-100 while running."
                    },
                    "error": {
                      "type": "string",
                      "nullable": true,
                      "description": "Present when status is failed."
                    },
                    "output_asset_id": {
                      "type": "string",
                      "nullable": true
                    },
                    "download_url": {
                      "type": "string",
                      "description": "Presigned download for the output. Present only once status is done, and it expires."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No API key, or a key that is invalid, expired or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The key's plan or scopes do not permit this operation.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such job, or it belongs to another key's owner.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. See Retry-After.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable machine-readable error code."
                        },
                        "message": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks": {
      "get": {
        "summary": "List webhook endpoints",
        "tags": [
          "Webhooks"
        ],
        "description": "List every webhook endpoint registered for this API key's owner.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "The registered endpoints.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "endpoints": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string"
                          },
                          "events": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "enabled": {
                            "type": "boolean"
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No API key, or a key that is invalid, expired or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Register a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "description": "Register an endpoint to receive job_completed and job_failed deliveries. The signing secret is returned once, at creation, and never again.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048,
                    "description": "HTTPS URL to deliver to."
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "job_completed",
                        "job_failed"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 2,
                    "default": [
                      "job_completed",
                      "job_failed"
                    ],
                    "description": "Events to deliver. Defaults to both."
                  }
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Created. Store the secret now.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "secret": {
                      "type": "string",
                      "description": "HMAC-SHA256 signing secret. Shown once."
                    },
                    "endpoint": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "enabled": {
                          "type": "boolean"
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    },
                    "warning": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The URL or event list is invalid.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "401": {
            "description": "No API key, or a key that is invalid, expired or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{id}": {
      "delete": {
        "summary": "Delete a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "description": "Permanently remove an endpoint. Undelivered retries for it are abandoned.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The webhook endpoint id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Deleted."
                }
              }
            }
          },
          "401": {
            "description": "No API key, or a key that is invalid, expired or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such endpoint for this owner.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Update a webhook endpoint",
        "tags": [
          "Webhooks"
        ],
        "description": "Change an endpoint's URL, event list, or enabled state. Send at least one field.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "job_completed",
                        "job_failed"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 2,
                    "default": [
                      "job_completed",
                      "job_failed"
                    ],
                    "description": "Events to deliver. Defaults to both."
                  },
                  "enabled": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The webhook endpoint id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "The updated endpoint.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "endpoint": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "enabled": {
                          "type": "boolean"
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No API key, or a key that is invalid, expired or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such endpoint for this owner.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhooks/{id}/rotate-secret": {
      "post": {
        "summary": "Rotate a webhook signing secret",
        "tags": [
          "Webhooks"
        ],
        "description": "Issue a new signing secret and invalidate the old one immediately. The new secret is returned once.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "path",
            "name": "id",
            "required": true,
            "description": "The webhook endpoint id."
          }
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "The new secret.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "secret": {
                      "type": "string",
                      "description": "New HMAC-SHA256 signing secret. Shown once."
                    },
                    "warning": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No API key, or a key that is invalid, expired or revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No such endpoint for this owner.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key"
      }
    },
    "schemas": {}
  }
}
