curl -X POST "https://api.hooked.so/v1/media/import" \
-H "x-api-key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "url": "https://cdn.example.com/products/serum.png", "name": "Serum bottle" }'
const response = await fetch("https://api.hooked.so/v1/media/import", {
method: "POST",
headers: { "x-api-key": process.env.HOOKED_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ url: "https://cdn.example.com/products/serum.png", name: "Serum bottle" }),
});
const { data } = await response.json();
// Poll GET /v1/media/{mediaId} until status is COMPLETED
console.log(data.mediaId, data.status);
import os
import requests
response = requests.post(
"https://api.hooked.so/v1/media/import",
headers={"x-api-key": os.environ["HOOKED_API_KEY"]},
json={"url": "https://cdn.example.com/products/serum.png", "name": "Serum bottle"},
)
data = response.json()["data"]
print(data["mediaId"], data["status"])
{
"success": true,
"message": "Import started",
"data": {
"mediaId": "cm4x9r2t50007ab12gh34ij78",
"status": "PROCESSING"
}
}
{
"success": false,
"message": "url: Must be a public https URL"
}
Media library
Import Media from URL
Add an image or video at a public URL to your media library
POST
/
v1
/
media
/
import
curl -X POST "https://api.hooked.so/v1/media/import" \
-H "x-api-key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "url": "https://cdn.example.com/products/serum.png", "name": "Serum bottle" }'
const response = await fetch("https://api.hooked.so/v1/media/import", {
method: "POST",
headers: { "x-api-key": process.env.HOOKED_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ url: "https://cdn.example.com/products/serum.png", name: "Serum bottle" }),
});
const { data } = await response.json();
// Poll GET /v1/media/{mediaId} until status is COMPLETED
console.log(data.mediaId, data.status);
import os
import requests
response = requests.post(
"https://api.hooked.so/v1/media/import",
headers={"x-api-key": os.environ["HOOKED_API_KEY"]},
json={"url": "https://cdn.example.com/products/serum.png", "name": "Serum bottle"},
)
data = response.json()["data"]
print(data["mediaId"], data["status"])
{
"success": true,
"message": "Import started",
"data": {
"mediaId": "cm4x9r2t50007ab12gh34ij78",
"status": "PROCESSING"
}
}
{
"success": false,
"message": "url: Must be a public https URL"
}
Overview
Adds the file at a publichttps URL to your team’s media library, so you can use it in any create endpoint. The call answers 202 right away with the new mediaId; the file is downloaded after the response. Poll Get Media until status is COMPLETED, then pass the id as media. Or pass a webhook (with optional metadata) to be told once the import is COMPLETED or FAILED: see media webhooks.
JPEG, PNG, WEBP, GIF, MP4, MOV or WEBM, up to 100 MB. The type is read from the file itself, not from the URL or the host’s
Content-Type. The file counts against your plan’s storage. Importing is free.http addresses are refused with 400 before anything is created, and every redirect is checked the same way. A URL that cannot be downloaded, a file of another type, one over 100 MB or one that does not fit your storage leaves the media FAILED, with the reason in its error.
curl -X POST "https://api.hooked.so/v1/media/import" \
-H "x-api-key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{ "url": "https://cdn.example.com/products/serum.png", "name": "Serum bottle" }'
const response = await fetch("https://api.hooked.so/v1/media/import", {
method: "POST",
headers: { "x-api-key": process.env.HOOKED_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ url: "https://cdn.example.com/products/serum.png", name: "Serum bottle" }),
});
const { data } = await response.json();
// Poll GET /v1/media/{mediaId} until status is COMPLETED
console.log(data.mediaId, data.status);
import os
import requests
response = requests.post(
"https://api.hooked.so/v1/media/import",
headers={"x-api-key": os.environ["HOOKED_API_KEY"]},
json={"url": "https://cdn.example.com/products/serum.png", "name": "Serum bottle"},
)
data = response.json()["data"]
print(data["mediaId"], data["status"])
{
"success": true,
"message": "Import started",
"data": {
"mediaId": "cm4x9r2t50007ab12gh34ij78",
"status": "PROCESSING"
}
}
{
"success": false,
"message": "url: Must be a public https URL"
}
Errors
| Status | Message | Cause |
|---|---|---|
| 400 | Invalid JSON body | The body is not JSON. |
| 400 | url: Required | No url. |
| 400 | url: Must be a public https URL | Not a URL, not https, or a local or private address. |
| 400 | webhook: Must be a valid HTTPS URL | webhook is not a public https URL. |
| 400 | metadata: Metadata cannot exceed 5KB | metadata is larger than 5 KB once serialized. |
| 401 | code: "not_authenticated" | Missing or invalid x-api-key. |
| 403 | code: "entitlement_required" | Your team does not have the Hooked app product. |
FAILED in Get Media, and its error says which.
The file is on your own machine? Use Upload Media instead.
Authorizations
Headers
Makes the request safe to retry. 1-255 printable ASCII characters, one per operation (your job id, or a UUID you store), reused on every retry. Within 24 hours the same key with the same body answers with the first response and the header Idempotent-Replayed: true, without running or charging again. Keys are scoped to your team and the endpoint. 5xx answers and refusals before anything ran (401, 402, 403, 409, 429) are not kept. See Idempotency.
Required string length:
1 - 255Pattern:
^[\x20-\x7E]+$Body
application/json
Public https URL of the file. Private, local and plain http addresses are refused.
Name in your library. Defaults to the file name in the URL.
Any JSON object of your own (max 5 KB). Sent back in the webhook payload.