Create a webhook
Sets the webhook of the account, the same one as in the dashboard. job.* events are sent for jobs created with /v2, conversion.* events for conversions created with /v1. An account has one webhook: if it has one already, the answer is 409. signing_secret is only in this response.
https://api.switchfile.io/v2/webhooksExample
curl "https://api.switchfile.io/v2/webhooks" \
-H "Authorization: Bearer $SWITCHFILE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/hooks/switchfile",
"events": [
"job.finished",
"job.failed"
]
}'const res = await fetch("https://api.switchfile.io/v2/webhooks", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SWITCHFILE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://example.com/hooks/switchfile",
events: [
"job.finished",
"job.failed"
]
}),
});
if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
console.log(await res.json());<?php
$ch = curl_init('https://api.switchfile.io/v2/webhooks');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'url' => 'https://example.com/hooks/switchfile',
'events' => [
'job.finished',
'job.failed',
],
]),
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('SWITCHFILE_API_KEY'),
'Content-Type: application/json',
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
curl_close($ch);
if ($status >= 400) {
throw new RuntimeException("HTTP $status: $response");
}
print_r(json_decode($response, true));import os
import requests
res = requests.post(
"https://api.switchfile.io/v2/webhooks",
headers={"Authorization": f"Bearer {os.environ['SWITCHFILE_API_KEY']}"},
json={
"url": "https://example.com/hooks/switchfile",
"events": [
"job.finished",
"job.failed",
],
},
)
res.raise_for_status()
print(res.json())Request body
eventsstring[]requiredat least 1 items
urlstringrequiredPublic http or https URL on port 80 or 443
1 to 2048 characters
Responses
201Created
dataCreatedWebhookrequireddata.created_atstringrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.disabledbooleanrequiredAlways false: switchfile does not disable webhooks on its own
data.eventsstring[]requireddata.failingbooleanrequiredThe last delivery to this URL failed
data.idstringrequiredID of the webhook (a UUID; CloudConvert uses an integer)
data.last_error_atstring | nullrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.last_response_codestring | nullrequiredHTTP status of the last failed delivery, or NETWORK_ERROR
data.linksobjectrequireddata.links.selfstringrequireddata.signing_secretstringrequiredSigning secret of the account. Only in this response
data.updated_atstringrequiredISO 8601 timestamp, for example 2026-11-06T18:00:00+00:00
data.urlstringrequired
201 application/json{ "data": { "id": "1a7e3c5b-9d2f-4b6a-8e0c-5f3d1b7a9c24", "url": "https://example.com/hooks/switchfile", "disabled": false, "events": [ "job.finished", "job.failed" ], "failing": false, "last_error_at": null, "last_response_code": null, "created_at": "2026-11-06T18:00:00+00:00", "updated_at": "2026-11-06T18:00:00+00:00", "links": { "self": "https://api.switchfile.io/v2/webhooks/1a7e3c5b-9d2f-4b6a-8e0c-5f3d1b7a9c24" }, "signing_secret": "your-signing-secret" } }401The API key is missing or not valid
UNAUTHENTICATED401 application/json{ "message": "Missing or invalid API key.", "code": "UNAUTHENTICATED" }404Does not exist for this account
NOT_FOUND404 application/json{ "message": "Job not found.", "code": "NOT_FOUND" }409The account has a webhook already. Delete it first or change it in the dashboard
WEBHOOK_EXISTS409 application/json{ "message": "This account already has a webhook. switchfile has one webhook per account: delete it first or change it in the dashboard.", "code": "WEBHOOK_EXISTS" }411The request has a body but no Content-Length header
LENGTH_REQUIRED411 application/json{ "message": "A Content-Length header is required for this request.", "code": "LENGTH_REQUIRED" }413The request or the file is too large
PAYLOAD_TOO_LARGE413 application/json{ "message": "The request body is larger than the allowed maximum.", "code": "PAYLOAD_TOO_LARGE" }422The URL is not a public http or https address, or an event is unknown
INVALID_DATA422 application/json{ "message": "url: The URL points to a private, reserved or own network address.", "code": "INVALID_DATA", "errors": { "url": [ "The URL points to a private, reserved or own network address." ] } }429Too many requests or a daily quota is used up. See Retry-After
RATE_LIMIT_EXCEEDED429 application/json{ "message": "Too many requests. Try again in 12 seconds.", "code": "RATE_LIMIT_EXCEEDED" }