Skip to content
APIonWeb

Developer Docs

Webhooks

Browse documentation

Asynchronous Virtual Try-On categories (shirt, tshirt, dress, jacket, pants, full_outfit) can notify your server when a job finishes, instead of you polling the status endpoint. Include an optional webhook_url field in the initial request:

POST /v1/virtual-try-on
{
  "category": "shirt",
  "person_image": "https://example.com/person.jpg",
  "product_image": "https://example.com/shirt.jpg",
  "webhook_url": "https://your-app.com/webhooks/apionweb"
}

What gets delivered

When the job finishes, APIonWeb sends an HTTP POST to your webhook_url with a JSON body in the same shape as GET /v1/virtual-try-on/{request_id} — see Responses for the full field reference.

On success:

Webhook payload
{
  "request_id": "3af9c2e1-7b4a-4d3e-9c1a-5e8f2b6d4a10",
  "status": "success",
  "category": "shirt",
  "result": {
    "image_url": "https://cdn.apionweb.com/results/3af9c2e1....png"
  },
  "cost": {
    "amount": "0.15",
    "currency": "USD"
  },
  "processing_time_ms": 6420
}

On failure:

Webhook payload
{
  "request_id": "3af9c2e1-7b4a-4d3e-9c1a-5e8f2b6d4a10",
  "status": "failed",
  "category": "shirt",
  "result": null,
  "cost": null,
  "error": {
    "code": "processing_failed",
    "message": "The try-on could not be generated from the provided images."
  }
}

Receiving a webhook

Your endpoint must be a publicly reachable URL that accepts a JSON POST body and responds quickly with a 2xx status. Do any slow work (image processing, notifying users) after acknowledging the webhook, not before.

routes/web.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::post('/webhooks/apionweb', function (Request $request) {
    $payload = $request->validate([
        'request_id' => ['required', 'string'],
        'status' => ['required', 'string'],
    ]);

    // Look up the job you stored locally when you submitted the request,
    // using $payload['request_id'], and update it based on $request->all().

    return response()->noContent();
});
Match incoming webhooks to your own records with request_id, the same id returned from the original POST. If you never receive a webhook for a job (network issues on either end can happen), the status endpoint is always available as a fallback — webhook_url is a convenience, not a replacement for it.

webhook_url is ignored for synchronous categories (glasses, sunglasses, hats, jewelry, shoes) since those already return the result in the initial response.