Skip to main content

Authentication

Every request must say who you are. There are two ways: the API key alone (simple, works everywhere) or a signed request (more secure). Most people only need the first one.

Send two headers with every request:

Authorization: YOUR_API_KEY
Content-Type: application/json
Common mistake

Put only the key in Authorization. No Bearer , no Token , no quotes. Authorization: Bearer abc123 is rejected with a 401 error.

Example:

const response = await fetch("https://app.icypeas.com/api/email-verification", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: "YOUR_API_KEY",
},
body: JSON.stringify({ email: "test@icypeas.com" }),
});
console.log(await response.json());

This is the method to use with no-code tools (Make, Zapier, n8n, Google Sheets).

Option 2: signed requests​

If your key could be intercepted, or your security policy requires it, sign each request with your API secret (on the API page, Reveal the secret Key). A signature is valid for one URL, one method and one moment, so a captured request can't be replayed.

Send these headers:

HeaderValue
AuthorizationYOUR_API_KEY:SIGNATURE
X-ROCK-TIMESTAMPThe current UTC time in ISO 8601, for example 2026-03-12T12:01:02.000Z
Content-Typeapplication/json

How to compute the signature​

  1. Take the HTTP method, for example POST.
  2. Take the path of the URL, for example /api/a/actions/subscription-information for https://app.icypeas.com/api/a/actions/subscription-information.
  3. Take the same timestamp you send in X-ROCK-TIMESTAMP.
  4. Join the three, in lower case: post/api/a/actions/subscription-information2026-03-12t12:01:02.000z.
  5. Compute the HMAC-SHA1 of that string with your API secret, as a hexadecimal string.
import crypto from "node:crypto";

function sign(url, method, secret, timestamp = new Date().toISOString()) {
const path = new URL(url).pathname;
const payload = `${method}${path}${timestamp}`.toLowerCase();
const signature = crypto.createHmac("sha1", secret).update(payload).digest("hex");
return { signature, timestamp };
}

const url = "https://app.icypeas.com/api/email-verification";
const { signature, timestamp } = sign(url, "POST", process.env.ICYPEAS_API_SECRET);

const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `${process.env.ICYPEAS_API_KEY}:${signature}`,
"X-ROCK-TIMESTAMP": timestamp,
},
body: JSON.stringify({ email: "test@icypeas.com" }),
});

Examples in more languages (Go, Rust…) are available on the API page of the app.

Authentication errors​

If authentication fails, you get an HTTP 401:

{
"message": "Unauthorized access.",
"error": "UnauthorizedAccessError",
"status": 401,
"code": "unauthorized_access_error"
}

Check, in this order: API access is activated, the key is complete and has no extra space, there's no Bearer prefix, and (for signed requests) your clock is on time and the path includes /api. See Errors for everything else.