The ProxyHat API authenticates every request with a Bearer token. Obtain a token by registering or logging in through the API, or by creating an API key in your dashboard. Send that token in the Authorization header on every authenticated request.
Bearer Tokens
Authenticated endpoints expect the Authorization header with your token:
Authorization: Bearer __API_KEY__
The base URL for all endpoints is https://api.proxyhat.com/v1. Tokens are Laravel Sanctum personal access tokens — they do not expire on their own and stay valid until you revoke or regenerate them.
Which token do I use? The accessToken returned by /v1/auth/register and /v1/auth/login, the plain_text_token returned by /v1/profile/api-keys, and a key created in the dashboard are all interchangeable Bearer tokens. Use whichever is most convenient for your integration.
Getting a Token
There are three ways to obtain a Bearer token:
Dashboard — open the API page and create a key. It is shown once; copy and store it securely.
Register or log in via the API — the endpoints below return an accessToken you can use immediately.
Create an API key programmatically — call POST /v1/profile/api-keys with an existing token.
Register
POST/v1/auth/register
Register
Register
Create a new ProxyHat account and receive a Bearer access token in one call. No authentication is required. The password must be at least 8 characters and contain upper- and lower-case letters and at least one number.
Example request:
Request Body
Name
Type
Required
Description
email
string
Required
Account email address. Must be a valid, unique email (max 255 characters).
password
string
Required
Minimum 8 characters, must include mixed case and at least one number (e.g. "SecurePass123").
password_confirmation
string
Required
Must match the password field.
name
string
Optional
Display name. If omitted, a name is derived from the email local part.
referral_code
string
Optional
Optional referral code to credit a referrer (max 64 characters).
If validation fails (duplicate email, weak password, mismatched confirmation) the API returns 422 Unprocessable Content with a Laravel validation body: { "message": "...", "errors": { "email": ["..."], "password": ["..."] } }.
Log In
POST/v1/auth/login
Log In
Log In
Exchange email and password for a Bearer access token. If two-factor authentication is enabled on the account, include the current TOTP (or a recovery) code in twofa_code.
Example request:
Request Body
Name
Type
Required
Description
email
string
Required
Account email address.
password
string
Required
Account password.
twofa_code
string
Optional
Six-digit TOTP code or a one-time recovery code. Required only when 2FA is enabled (max 16 characters).
import requests
response = requests.post(
"https://api.proxyhat.com/v1/auth/login",
headers={"Accept": "application/json"},
json={
"email": "you@example.com",
"password": "SecurePass123",
# "twofa_code": "123456", # only if 2FA is enabled
},
)
data = response.json()
access_token = data["accessToken"]
print(access_token)
const response = await fetch("https://api.proxyhat.com/v1/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json",
},
body: JSON.stringify({
email: "you@example.com",
password: "SecurePass123",
// twofa_code: "123456", // only if 2FA is enabled
}),
});
const data = await response.json();
console.log(data.accessToken);
payload := map[string]string{
"email": "you@example.com",
"password": "SecurePass123",
// "twofa_code": "123456", // only if 2FA is enabled
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", "https://api.proxyhat.com/v1/auth/login", bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
var data struct {
AccessToken string `json:"accessToken"`
TokenType string `json:"tokenType"`
}
json.NewDecoder(resp.Body).Decode(&data)
fmt.Println(data.AccessToken)
Login Error Responses
Invalid email or password returns 401 Unauthorized with a flat body:
{
"message": "Unauthorized"
}
When 2FA is enabled but no twofa_code was supplied, the API returns 403 Forbidden using the standard response envelope. Note there is no message key — the human-readable text is in description, and requires_2fa signals that you should prompt for a code and retry:
Issue a new long-lived API key for the authenticated account. The plaintext token is returned only in this response and cannot be retrieved again — store it immediately.
Example request:
Request Body
Name
Type
Required
Description
name
string
Optional
Label for the key. Defaults to "API key <timestamp>" if omitted.
abilities
array
Optional
Token abilities/scopes. Defaults to ["*"] (full access).
body, _ := json.Marshal(map[string]string{"name": "Production server"})
req, _ := http.NewRequest("POST", "https://api.proxyhat.com/v1/profile/api-keys", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer __API_KEY__")
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
var data struct {
ID int `json:"id"`
Name string `json:"name"`
PlainTextToken string `json:"plain_text_token"`
}
json.NewDecoder(resp.Body).Decode(&data)
fmt.Println(data.PlainTextToken) // shown only once
Stored once, no id| prefix. Unlike the raw Sanctum token format, plain_text_token is returned with the numeric id and pipe stripped off — use the value exactly as returned. It is shown only in this response (and when you regenerate a key); ProxyHat cannot show it to you again. If you lose it, delete the key and create a new one.
Using the Token
Once you have a token, send it as a Bearer credential. A quick way to confirm it works is the /v1/auth/user "whoami" endpoint, which returns your account and traffic balance:
If the token is missing, malformed, or has been revoked, authenticated endpoints return 401 Unauthorized with a flat body:
{
"message": "Unauthenticated."
}
Token Security
Important: Treat your token like a password. Never expose it in client-side code, public repositories, or shared logs. If a token is compromised, delete or regenerate it immediately from the dashboard or via the API.
Store tokens in environment variables, not in source code.
Use separate keys for development and production.
Rotate keys periodically and delete unused ones.
To end a session created via login, call POST /v1/auth/logout, which revokes the current token.