Audio Started
curl --request POST \
--url https://your-webhook.com/audio.started \
--header 'Content-Type: application/json' \
--header 'magic-hour-event-signature: <magic-hour-event-signature>' \
--header 'magic-hour-event-timestamp: <magic-hour-event-timestamp>' \
--data '
{
"type": "audio.started",
"payload": {
"id": "cuid-example",
"name": "Example Name",
"status": "complete",
"type": "VOICE_GENERATOR",
"created_at": "2023-11-07T05:31:56Z",
"enabled": true,
"credits_charged": 2,
"downloads": [
{
"url": "https://videos.magichour.ai/id/output.wav",
"expires_at": "2024-10-19T05:16:19.027Z"
}
],
"error": null
}
}
'import requests
url = "https://your-webhook.com/audio.started"
payload = {
"type": "audio.started",
"payload": {
"id": "cuid-example",
"name": "Example Name",
"status": "complete",
"type": "VOICE_GENERATOR",
"created_at": "2023-11-07T05:31:56Z",
"enabled": True,
"credits_charged": 2,
"downloads": [
{
"url": "https://videos.magichour.ai/id/output.wav",
"expires_at": "2024-10-19T05:16:19.027Z"
}
],
"error": None
}
}
headers = {
"magic-hour-event-signature": "<magic-hour-event-signature>",
"magic-hour-event-timestamp": "<magic-hour-event-timestamp>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'magic-hour-event-signature': '<magic-hour-event-signature>',
'magic-hour-event-timestamp': '<magic-hour-event-timestamp>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: 'audio.started',
payload: {
id: 'cuid-example',
name: 'Example Name',
status: 'complete',
type: 'VOICE_GENERATOR',
created_at: '2023-11-07T05:31:56Z',
enabled: true,
credits_charged: 2,
downloads: [
{
url: 'https://videos.magichour.ai/id/output.wav',
expires_at: '2024-10-19T05:16:19.027Z'
}
],
error: null
}
})
};
fetch('https://your-webhook.com/audio.started', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://your-webhook.com/audio.started",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => 'audio.started',
'payload' => [
'id' => 'cuid-example',
'name' => 'Example Name',
'status' => 'complete',
'type' => 'VOICE_GENERATOR',
'created_at' => '2023-11-07T05:31:56Z',
'enabled' => true,
'credits_charged' => 2,
'downloads' => [
[
'url' => 'https://videos.magichour.ai/id/output.wav',
'expires_at' => '2024-10-19T05:16:19.027Z'
]
],
'error' => null
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"magic-hour-event-signature: <magic-hour-event-signature>",
"magic-hour-event-timestamp: <magic-hour-event-timestamp>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-webhook.com/audio.started"
payload := strings.NewReader("{\n \"type\": \"audio.started\",\n \"payload\": {\n \"id\": \"cuid-example\",\n \"name\": \"Example Name\",\n \"status\": \"complete\",\n \"type\": \"VOICE_GENERATOR\",\n \"created_at\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true,\n \"credits_charged\": 2,\n \"downloads\": [\n {\n \"url\": \"https://videos.magichour.ai/id/output.wav\",\n \"expires_at\": \"2024-10-19T05:16:19.027Z\"\n }\n ],\n \"error\": null\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("magic-hour-event-signature", "<magic-hour-event-signature>")
req.Header.Add("magic-hour-event-timestamp", "<magic-hour-event-timestamp>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://your-webhook.com/audio.started")
.header("magic-hour-event-signature", "<magic-hour-event-signature>")
.header("magic-hour-event-timestamp", "<magic-hour-event-timestamp>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"audio.started\",\n \"payload\": {\n \"id\": \"cuid-example\",\n \"name\": \"Example Name\",\n \"status\": \"complete\",\n \"type\": \"VOICE_GENERATOR\",\n \"created_at\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true,\n \"credits_charged\": 2,\n \"downloads\": [\n {\n \"url\": \"https://videos.magichour.ai/id/output.wav\",\n \"expires_at\": \"2024-10-19T05:16:19.027Z\"\n }\n ],\n \"error\": null\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-webhook.com/audio.started")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["magic-hour-event-signature"] = '<magic-hour-event-signature>'
request["magic-hour-event-timestamp"] = '<magic-hour-event-timestamp>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"audio.started\",\n \"payload\": {\n \"id\": \"cuid-example\",\n \"name\": \"Example Name\",\n \"status\": \"complete\",\n \"type\": \"VOICE_GENERATOR\",\n \"created_at\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true,\n \"credits_charged\": 2,\n \"downloads\": [\n {\n \"url\": \"https://videos.magichour.ai/id/output.wav\",\n \"expires_at\": \"2024-10-19T05:16:19.027Z\"\n }\n ],\n \"error\": null\n }\n}"
response = http.request(request)
puts response.read_body{
"message": "Success message from your endpoint"
}{
"message": "Error message from your endpoint"
}{
"message": "Error message from your endpoint"
}Audio Events
Audio Started
Magic Hour notifies your server when an audio project begins processing. Webhook reference for timestamp and signature headers plus JSON body for voice and audio jobs.
POST
/
audio.started
Audio Started
curl --request POST \
--url https://your-webhook.com/audio.started \
--header 'Content-Type: application/json' \
--header 'magic-hour-event-signature: <magic-hour-event-signature>' \
--header 'magic-hour-event-timestamp: <magic-hour-event-timestamp>' \
--data '
{
"type": "audio.started",
"payload": {
"id": "cuid-example",
"name": "Example Name",
"status": "complete",
"type": "VOICE_GENERATOR",
"created_at": "2023-11-07T05:31:56Z",
"enabled": true,
"credits_charged": 2,
"downloads": [
{
"url": "https://videos.magichour.ai/id/output.wav",
"expires_at": "2024-10-19T05:16:19.027Z"
}
],
"error": null
}
}
'import requests
url = "https://your-webhook.com/audio.started"
payload = {
"type": "audio.started",
"payload": {
"id": "cuid-example",
"name": "Example Name",
"status": "complete",
"type": "VOICE_GENERATOR",
"created_at": "2023-11-07T05:31:56Z",
"enabled": True,
"credits_charged": 2,
"downloads": [
{
"url": "https://videos.magichour.ai/id/output.wav",
"expires_at": "2024-10-19T05:16:19.027Z"
}
],
"error": None
}
}
headers = {
"magic-hour-event-signature": "<magic-hour-event-signature>",
"magic-hour-event-timestamp": "<magic-hour-event-timestamp>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'magic-hour-event-signature': '<magic-hour-event-signature>',
'magic-hour-event-timestamp': '<magic-hour-event-timestamp>',
'Content-Type': 'application/json'
},
body: JSON.stringify({
type: 'audio.started',
payload: {
id: 'cuid-example',
name: 'Example Name',
status: 'complete',
type: 'VOICE_GENERATOR',
created_at: '2023-11-07T05:31:56Z',
enabled: true,
credits_charged: 2,
downloads: [
{
url: 'https://videos.magichour.ai/id/output.wav',
expires_at: '2024-10-19T05:16:19.027Z'
}
],
error: null
}
})
};
fetch('https://your-webhook.com/audio.started', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://your-webhook.com/audio.started",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => 'audio.started',
'payload' => [
'id' => 'cuid-example',
'name' => 'Example Name',
'status' => 'complete',
'type' => 'VOICE_GENERATOR',
'created_at' => '2023-11-07T05:31:56Z',
'enabled' => true,
'credits_charged' => 2,
'downloads' => [
[
'url' => 'https://videos.magichour.ai/id/output.wav',
'expires_at' => '2024-10-19T05:16:19.027Z'
]
],
'error' => null
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"magic-hour-event-signature: <magic-hour-event-signature>",
"magic-hour-event-timestamp: <magic-hour-event-timestamp>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://your-webhook.com/audio.started"
payload := strings.NewReader("{\n \"type\": \"audio.started\",\n \"payload\": {\n \"id\": \"cuid-example\",\n \"name\": \"Example Name\",\n \"status\": \"complete\",\n \"type\": \"VOICE_GENERATOR\",\n \"created_at\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true,\n \"credits_charged\": 2,\n \"downloads\": [\n {\n \"url\": \"https://videos.magichour.ai/id/output.wav\",\n \"expires_at\": \"2024-10-19T05:16:19.027Z\"\n }\n ],\n \"error\": null\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("magic-hour-event-signature", "<magic-hour-event-signature>")
req.Header.Add("magic-hour-event-timestamp", "<magic-hour-event-timestamp>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://your-webhook.com/audio.started")
.header("magic-hour-event-signature", "<magic-hour-event-signature>")
.header("magic-hour-event-timestamp", "<magic-hour-event-timestamp>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"audio.started\",\n \"payload\": {\n \"id\": \"cuid-example\",\n \"name\": \"Example Name\",\n \"status\": \"complete\",\n \"type\": \"VOICE_GENERATOR\",\n \"created_at\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true,\n \"credits_charged\": 2,\n \"downloads\": [\n {\n \"url\": \"https://videos.magichour.ai/id/output.wav\",\n \"expires_at\": \"2024-10-19T05:16:19.027Z\"\n }\n ],\n \"error\": null\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-webhook.com/audio.started")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["magic-hour-event-signature"] = '<magic-hour-event-signature>'
request["magic-hour-event-timestamp"] = '<magic-hour-event-timestamp>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"audio.started\",\n \"payload\": {\n \"id\": \"cuid-example\",\n \"name\": \"Example Name\",\n \"status\": \"complete\",\n \"type\": \"VOICE_GENERATOR\",\n \"created_at\": \"2023-11-07T05:31:56Z\",\n \"enabled\": true,\n \"credits_charged\": 2,\n \"downloads\": [\n {\n \"url\": \"https://videos.magichour.ai/id/output.wav\",\n \"expires_at\": \"2024-10-19T05:16:19.027Z\"\n }\n ],\n \"error\": null\n }\n}"
response = http.request(request)
puts response.read_body{
"message": "Success message from your endpoint"
}{
"message": "Error message from your endpoint"
}{
"message": "Error message from your endpoint"
}Headers
A signatured created with the webhook secret key and a signed_payload, using HMAC with SHA-256
Example:
"3e771b50c..."
Time in seconds since the epoch. Use this value to check whether the request is within a reasonable window of the current time. Usually less than 5 minutes.
Example:
"1730742038"
Body
application/json
Body
Response
Success
Success
Example:
"Success message from your endpoint"
Was this page helpful?
⌘I