ScriptHaul API
Log inGet API key

Authentication and keys

ScriptHaul accounts are verified email addresses. Codes last 10 minutes; five wrong attempts lock that code for 15 minutes. Addresses are normalized before uniqueness checks.

Accounts are created on the website, not by script: the sign-up form on api.scripthaul.com and the dashboard carry a Cloudflare Turnstile check, and POST /v1/auth/code refuses a request without its token in production. One network can verify at most three accounts per rolling 30 days; disposable email domains are refused. REST calls use your Bearer key; MCP assistants can also connect through OAuth.

OAuth for assistants

Use your assistant's MCP setup guide to connect to https://api.scripthaul.com/mcp without pasting an API key. OAuth uses dynamic client registration, authorization codes with PKCE S256, and refresh tokens. The browser opens ScriptHaul email-code sign-in and consent naming the client, the redirect destination host, and scope mcp. Review the destination before approving.

An OAuth grant can use account MCP tools, create jobs, and spend credits. It cannot see or create API keys, and its token is limited to the MCP endpoint. All of an account's OAuth grants share one tier allowance pool: request rate, cold-fetch and search concurrency, cold fetches, cache reads, cold enumerations, search pages and attempts, channel resolution, latest uploads, library coverage, and library searches. Daily usage from revoked grants still counts, so reconnecting does not reset the pool. Ordinary API keys retain their independent per-key limits. Search's 60-second free replay remains specific to the same grant, including after token refresh.

The account can keep up to ten unrevoked grants. A new completed connection revokes the oldest grant by creation date when needed. Expired connections remain listed until revoked or replaced. Merely approving consent creates no grant or metering identity; the client must redeem its authorization code. In Dashboard → Connected apps, inspect client names, creation dates, and last-used dates, or revoke a grant. Revocation clears the local authentication cache immediately; an access token already memoized elsewhere may work for up to 30 seconds, never beyond its own expiry. Refresh-token revocation is immediate. Last-used dates update at most once per five minutes. API keys remain separately managed below.

Access tokens last one hour. The refresh grant expires 30 days after the first code exchange; refreshing does not move that deadline. Client registrations also expire after 30 days and can require an earlier reconnection. Reconnect when your assistant requests it, no later than 30 days. Registration and token requests have their own limits, separate from human email sign-in: 30 registrations per minute per address and 600 token requests per minute per client/address pair. Registration also has a server-wide capacity limit. A registration may not use the ScriptHaul or BulkTranscripts name in any spelling; the consent screen shows the app's redirect host and says its name is the developer's own, not reviewed by ScriptHaul, so check both before you connect. Respect Retry-After on throttled requests.

Clients discover the endpoints through protected-resource metadata and authorization-server metadata. The protected resource is https://api.scripthaul.com/mcp; the only scope is mcp. An unauthenticated MCP response supplies this resource-specific metadata URL in WWW-Authenticate, which browser clients can read through CORS.

Bearer only

Send keys only in the Authorization header.

Authorization: Bearer sh_live_…

Keys in api_key, key, token, or similar query parameters are rejected. ScriptHaul stores only a peppered SHA-256 key hash and a 12-character display prefix.

List and create keys

curl https://api.scripthaul.com/v1/keys \
  -H "Authorization: Bearer $SCRIPTHAUL_API_KEY"

curl https://api.scripthaul.com/v1/keys \
  -X POST \
  -H "Authorization: Bearer $SCRIPTHAUL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Production","daily_credit_cap":250}'

Free accounts may hold 2 live keys; paid accounts may hold 5. daily_credit_cap is an optional customer-controlled kill switch.

Revoke or rotate

curl https://api.scripthaul.com/v1/keys/KEY_ID \
  -X DELETE \
  -H "Authorization: Bearer $SCRIPTHAUL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"grace_period_hours":0}'

curl https://api.scripthaul.com/v1/keys/KEY_ID/rotate \
  -X POST \
  -H "Authorization: Bearer $SCRIPTHAUL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'

Rotation creates a new key and gives the old key a 24-hour grace period. Immediate revocation uses 0; scheduled revocation uses 24. Authentication lookups are memoized for up to 30 seconds, so an immediately revoked key may continue to authenticate for at most that documented cache window.

Dashboard sessions

The dashboard uses an HttpOnly, Secure, SameSite=Strict cookie. It is accepted only on dashboard-safe account, key, usage, job-read, and checkout routes. It never authenticates transcript delivery or MCP calls. Cookie-authenticated mutations require X-ScriptHaul-Dashboard: 1.

List keys in four languages

These requests keep the credential in the header. Maintained runnable versions are in the examples directory.

curl https://api.scripthaul.com/v1/keys \
  -H "Authorization: Bearer $SCRIPTHAUL_API_KEY"
import os, urllib.request
request = urllib.request.Request("https://api.scripthaul.com/v1/keys")
request.add_header("Authorization", f"Bearer {os.environ['SCRIPTHAUL_API_KEY']}")
print(urllib.request.urlopen(request).read().decode())
const response = await fetch("https://api.scripthaul.com/v1/keys", {
  headers: { Authorization: `Bearer ${process.env.SCRIPTHAUL_API_KEY}` },
});
console.log(await response.json());
req, _ := http.NewRequest("GET", "https://api.scripthaul.com/v1/keys", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("SCRIPTHAUL_API_KEY"))
response, err := http.DefaultClient.Do(req)
if err != nil { log.Fatal(err) }
defer response.Body.Close()
io.Copy(os.Stdout, response.Body)