Authentication
Credentials
To access the Veryfi API programmatically, you will need to configure your client with the correct credentials. Make a copy of your CLIENT_ID
, Username
, and API Key
and paste them into their respective Client and Authorization locations.
- Go to the Keys section in Settings
- Make a copy of your
CLIENT_ID
- Make a copy of your
Username
andAPI Key
- Paste them into your Client and Authorization headers
Client Header
Client Header identifies the partner (ie. you) that is making the requests to Veryfi API.
CLIENT-ID: "CLIENT_ID"
Authorization Header
The Authorization Header provides credentials that authenticate a user agent with a server, allowing access to protected resources.
Required Keys
AUTHORIZATION: 'apikey `USERNAME:API_KEY`'
This is how your authorization header should look:
AUTHORIZATION: 'apikey api_demo:1f2pdas7jkj389d8sda'
The Interactive API is a convenient way to try API endpoints. Visit the Interactive API v8: Receipts & Invoices test from the portal.
Environment URL
To be able to make a request to Veryfi, you need a URL that consists of two parts: ENVIROMENT_URL
and ENDPOINT_URL
. Check the documentation below for the endpoint that best fits your business needs.
Required Keys
https://api.veryfi.com/
Signature and Timestamp Headers
All requests to Veryfi's endpoints should have X-Veryfi-Request-Signature
and X-Veryfi-Request-Timestamp
headers as an additional layer of authentication. A user encodes a POST request with the CLIENT_SECRET
signature. A signed POST request is the request itself and the signature from the request.
Example
A user sends a POST request to /Documents with a signature to process a new Document.
Veryfi checks the signature sent along with the signature on file. Since the authorized server knows the CLIENT_SECRET
, the server can validate and compare if the incoming request's signature coincides with the server's signature.
UTF-8 Encoding
Every string passed to and from the API needs to be UTF-8 encoded. For maximum compatibility, normalize to Unicode Normalization Form C (NFC) before UTF-8 encoding.
Signatures are valid for 30 minutes from the time of generation.
X-Veryfi-Request-Signature: "Generated Signature"
X-Veryfi-Request-Timestamp
value is a Unix Timestamp in milliseconds (ms) since epoch. Since CLIENT_SECRET
is essential to the application's password, it automatically does the signing when using a Veryfi SDK.
X-Veryfi-Request-Timestamp: "Unix Timestamp"
Refer to the code examples below for a demonstration of how the value of the X-Veryfi-Request-Signature
header is generated.
Code Samples
- Javascript
- Python
- Java
- Bash
const crypto = require('crypto')
function customSerialize(value) {
if (typeof value === 'object' && value !== null) {
if (Array.isArray(value)) {
return `[${value.map(customSerialize).join(', ')}]`
} else {
let nestedParts = []
for (const [nestedKey, nestedValue] of Object.entries(value)) {
nestedParts.push(`${nestedKey}: ${customSerialize(nestedValue)}`)
}
return `{${nestedParts.join(', ')}}`
}
}
return JSON.stringify(value)
}
function serializePayload(payload) {
let parts = []
for (const [key, value] of Object.entries(payload)) {
parts.push(`${key}:${customSerialize(value)}`)
}
return parts.join(',')
}
function createSignature(secret, payload, timestamp) {
let payloadStr = `timestamp:${timestamp},${serializePayload(payload)}`
console.log('Payload string:', payloadStr)
const hmac = crypto.createHmac('sha256', secret)
hmac.update(payloadStr)
return hmac.digest('base64')
}
const dt = new Date()
const utcSeconds = Math.floor(dt.getTime() / 1000)
const timestampMillisecond = utcSeconds * 1000
const requestPayload = {}
const clientSecret = ''
const signature = createSignature(
clientSecret,
requestPayload,
timestampMillisecond
)
console.log(signature)
const headers = {
'X-VERYFI-REQUEST-TIMESTAMP': timestampMillisecond.toString(),
'X-VERYFI-REQUEST-SIGNATURE': signature,
'CLIENT-ID': 'vrfKOMO1xSEM0AWNtKRpdemouT5M1Di8xxudemo',
AUTHORIZATION: 'apikey api_demo:4b1c01e8ce48ba08832cc299d808demo',
}
console.log(headers)
import base64
import calendar
import datetime
import hashlib
import hmac
from typing import Dict
dt = datetime.datetime.utcnow()
utc_seconds = calendar.timegm(dt.utctimetuple())
timestamp_millisecond = utc_seconds * 1000
request_payload = {}
client_secret = ""
def create_signature(secret: str, payload: Dict, timestamp: float) -> str:
payload_str = f"timestamp:{timestamp}"
for k, v in payload.items():
payload_str = f"{payload_str},{k}:{v}"
tmp_signature = hmac.new(
bytes(secret, "utf-8"), msg=bytes(payload_str, "utf-8"), digestmod=hashlib.sha256
).digest()
return str(base64.b64encode(tmp_signature), "utf-8").strip()
signature = create_signature(client_secret, request_payload, timestamp_millisecond)
headers = {
"X-VERYFI-REQUEST-TIMESTAMP": timestamp_millisecond,
"X-VERYFI-REQUEST-SIGNATURE": signature,
"CLIENT-ID": "vrfKOMO1xSEM0AWNtKRpdemouT5M1Di8xxudemo",
"AUTHORIZATION": "apikey api_demo:4b1c01e8ce48ba08832cc299d808demo",
}
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;
public String getSignature() {
String clientSecret = "CLIENT_SECRET";
String userId = "USER_ID";
// Build signature
Date date = new Date();
long timeStamp = date.getTime();
String message = "timestamp:" + timeStamp + ",user_id:" + userId;
SecretKeySpec keySpec = new SecretKeySpec(clientSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
Mac mac;
try {
mac = Mac.getInstance("HmacSHA256");
} catch (NoSuchAlgorithmException e) {
return e.getMessage();
}
try {
mac.init(keySpec);
} catch (InvalidKeyException e) {
return e.getMessage();
}
byte[] rawHmac = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
String base64SignatureEncoded = Base64.getEncoder().encodeToString(rawHmac);
return base64SignatureEncoded;
}
CLIENT_SECRET="CLIENT_SECRET"
user_id="USER_ID"
# Sign the request
timestamp=$(( $(date +%s) * 1000 ))
payload_to_sign="timestamp:${timestamp},user_id:${user_id}"
base64_signature=$(echo -n ${payload_to_sign} | openssl sha256 -hmac ${CLIENT_SECRET} -binary | base64)
API Keys Access Permissions
Verfyi provides additional control for Admin users when granting access to API Keys for safety and security reasons.
Admin users with access to API Keys can only grant API Keys to other Admins. API Keys are not available to non-Admin team members. Visit Managing my team workspace to learn more about managing team members.