Start here
Challenge it again
POST
/v1/webhooks/{id}on https://api.auray.ai/v1What a disabled endpoint needs after its server is fixed.
What a disabled endpoint needs after its server is fixed. An endpoint paused for failing too many times in a row kept every event it missed queued against it, and a challenge that passes sends them, oldest first; the webhooks guide says how long one is kept.
#Authentication
Authorization: Bearer auray_sk_… — webhooks:write.
#Request
#Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id | string | yes |
#Example request
curl -X POST https://api.auray.ai/v1/webhooks/photo_docs-mtpb1vnh \
-H "Authorization: Bearer $AURAY_API_KEY"import { createClient } from "@auray/client";
const auray = createClient(); // reads AURAY_API_KEY
console.log(await auray.platform.webhooks.verify("photo_docs-mtpb1vnh"));from auray_client import Client
auray = Client() # reads AURAY_API_KEY
print(auray.platform.webhooks.verify("photo_docs-mtpb1vnh"))const res = await fetch("https://api.auray.ai/v1/webhooks/photo_docs-mtpb1vnh", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.AURAY_API_KEY}` },
});
console.log(await res.json());import os, requests
r = requests.post(
"https://api.auray.ai/v1/webhooks/photo_docs-mtpb1vnh",
headers={"Authorization": f"Bearer {os.environ['AURAY_API_KEY']}"},
)
r.raise_for_status()
print(r.json())package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, err := http.NewRequest("POST", "https://api.auray.ai/v1/webhooks/photo_docs-mtpb1vnh", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("AURAY_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}<?php
$ch = curl_init("https://api.auray.ai/v1/webhooks/photo_docs-mtpb1vnh");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("AURAY_API_KEY"),
],
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $response, PHP_EOL;require "net/http"
uri = URI("https://api.auray.ai/v1/webhooks/photo_docs-mtpb1vnh")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("AURAY_API_KEY")}"
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.code, res.bodyimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.auray.ai/v1/webhooks/photo_docs-mtpb1vnh"))
.header("Authorization", "Bearer " + System.getenv("AURAY_API_KEY"))
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}using System.Net.Http.Headers;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("AURAY_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.auray.ai/v1/webhooks/photo_docs-mtpb1vnh");
using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");#Responses
#200 OK
OK
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
id | string | no | — | |
object | string | no | — | One of "webhook". |
url | string | no | — | A URL. |
products | string[] | no | — | |
status | string | no | — | active if the challenge succeeded just now, pending if it did not. One of "pending", "active". |
verified | boolean | no | — | |
verify_keys | string | no | — | Where the public keys that sign your deliveries are published. Fetch it, cache it, and look up the kid each Auray-Signature names. A URL rather than a key, because a copy handed back here would go stale the moment one is rotated — and free rotation is the point of the scheme. A URL. |
signature_algorithm | string | no | — | How Auray-Signature is signed: Ed25519 over <t>.<raw body>, the header reading t=…,v2=…,kid=…. THERE IS NO SHARED SECRET — this response used to return secret (whsec_…) for an HMAC scheme, and the same bytes that verified a delivery could forge one. The private half of this key never leaves the deployment. One key signs for every account, so the body names who it is for, inside what the signature covers: account (your account id, the id GET /v1/me returns) and webhook_id (the endpoint, or null for a per-request ?webhook). Compare account with yours and refuse anything else. One of "EdDSA". |
verification | object | no | — | Present ONLY when the challenge failed — and the response is still a success, because the endpoint was registered; it is your server that did not answer. |
verification.failed | string | no | — | Which check failed. |
verification.status | integer | no | — | The HTTP status your endpoint answered with, if it answered. May be null. |
verification.response | string | no | — | The first bytes of what it said. May be null. |
request_id | string | no | — | Mirrored in the X-Request-Id header. |
Headers:
| Header | Description |
|---|---|
RateLimit-Limit | Burst capacity. |
RateLimit-Remaining | |
RateLimit-Reset | Seconds until refill. |
X-RateLimit-Limit | |
X-RateLimit-Remaining | |
X-RateLimit-Reset | Unix seconds. The X- spelling is what client libraries read. |
X-Request-Id |
#401 Unauthorized
#403 Forbidden
#404 Not Found
#409 Conflict
#429 Too Many Requests
#500 Internal Server Error
webhook_read_failed — your endpoint could not be read. A failed lookup used to answer 404 not_found and send people off to re-register an endpoint that was working. Retry.
The error body: error, message, docs (the entry that explains it) and request_id.
#503 Service Unavailable
#Status codes
| Status | Meaning |
|---|---|
200 | OK |
401 | Unauthorized |
403 | Forbidden |
404 | Not Found |
409 | Conflict |
429 | Too Many Requests |
500 | webhook_read_failed — your endpoint could not be read. |
503 | Service Unavailable |
Every refusal names its code, and every code is explained at Errors.