Skip to main content

List Compliance Forms

Retrieve a paginated list of Compliance Forms to monitor merchant compliance status, track form completion, and manage PCI DSS requirements across your platform.

Overview

Use this endpoint to:

  • Monitor platform-wide compliance status
  • Find incomplete forms requiring merchant action
  • Track expired forms needing renewal
  • Filter by merchant to check specific merchant compliance
  • Generate compliance reports and analytics
  • Identify overdue forms approaching due dates

Use Cases

1. List All Compliance Forms

Get a paginated list of all compliance forms:

async function listAllComplianceForms(limit = 20) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/compliance_forms?limit=${limit}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const data = await response.json();

console.log(`Found ${data._embedded?.compliance_forms?.length || 0} forms`);
console.log('Has more:', data.has_more);

data._embedded?.compliance_forms?.forEach(form => {
console.log({
id: form.id,
merchant: form.linked_to,
type: form.type,
state: form.state,
due: new Date(form.due_at).toLocaleDateString(),
valid_until: new Date(form.valid_until).toLocaleDateString()
});
});

return data;
}

2. Find Incomplete Forms

Get all forms that need merchant completion:

async function findIncompleteForms() {
const response = await fetch(
'https://api.ahrvo.network/payments/na/compliance_forms?state=INCOMPLETE&limit=100',
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const data = await response.json();
const incompleteForms = data._embedded?.compliance_forms || [];

console.log(`Found ${incompleteForms.length} incomplete forms`);

// Sort by due date
const sortedForms = incompleteForms.sort((a, b) =>
new Date(a.due_at) - new Date(b.due_at)
);

// Identify overdue forms
const now = new Date();
const overdue = sortedForms.filter(form => new Date(form.due_at) < now);
const upcoming = sortedForms.filter(form => new Date(form.due_at) >= now);

console.log('Overdue forms:', overdue.length);
console.log('Upcoming due forms:', upcoming.length);

return {
all: incompleteForms,
overdue,
upcoming
};
}

3. Get Forms by Merchant

Retrieve all compliance forms for a specific merchant:

async function getMerchantForms(merchantId) {
const response = await fetch(
`https://api.ahrvo.network/payments/na/compliance_forms?linked_to=${merchantId}&limit=100`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const data = await response.json();
const forms = data._embedded?.compliance_forms || [];

const summary = {
merchant_id: merchantId,
total: forms.length,
by_state: {
INCOMPLETE: forms.filter(f => f.state === 'INCOMPLETE').length,
COMPLETE: forms.filter(f => f.state === 'COMPLETE').length,
EXPIRED: forms.filter(f => f.state === 'EXPIRED').length
},
by_type: {},
forms: forms
};

// Count by type
forms.forEach(form => {
summary.by_type[form.type] = (summary.by_type[form.type] || 0) + 1;
});

console.log('Merchant Compliance Summary:', summary);

return summary;
}

4. Find Expiring Forms

Identify forms expiring within a threshold:

async function findExpiringForms(daysThreshold = 30) {
const response = await fetch(
'https://api.ahrvo.network/payments/na/compliance_forms?state=COMPLETE&limit=100',
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const data = await response.json();
const completeForms = data._embedded?.compliance_forms || [];

const now = new Date();
const thresholdDate = new Date(now.getTime() + (daysThreshold * 24 * 60 * 60 * 1000));

const expiringForms = completeForms.filter(form => {
const validUntil = new Date(form.valid_until);
return validUntil > now && validUntil <= thresholdDate;
});

console.log(`Found ${expiringForms.length} forms expiring within ${daysThreshold} days`);

expiringForms.forEach(form => {
const validUntil = new Date(form.valid_until);
const daysRemaining = Math.ceil((validUntil - now) / (1000 * 60 * 60 * 24));

console.log({
id: form.id,
merchant: form.linked_to,
type: form.type,
days_remaining: daysRemaining,
valid_until: form.valid_until
});
});

return expiringForms;
}

5. Filter by State

Get forms in a specific state:

async function getFormsByState(state) {
// state can be: INCOMPLETE, COMPLETE, or EXPIRED
const response = await fetch(
`https://api.ahrvo.network/payments/na/compliance_forms?state=${state}&limit=100`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const data = await response.json();
const forms = data._embedded?.compliance_forms || [];

console.log(`Found ${forms.length} ${state} forms`);

return forms;
}

// Examples
const incompleteForms = await getFormsByState('INCOMPLETE');
const completedForms = await getFormsByState('COMPLETE');
const expiredForms = await getFormsByState('EXPIRED');

6. Generate Compliance Dashboard

Create comprehensive compliance analytics:

async function generateComplianceDashboard() {
// Fetch all forms (may need pagination for large datasets)
let allForms = [];
let cursor = null;

do {
const url = cursor
? `https://api.ahrvo.network/payments/na/compliance_forms?after_cursor=${cursor}&limit=100`
: 'https://api.ahrvo.network/payments/na/compliance_forms?limit=100';

const response = await fetch(url, {
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
});

const data = await response.json();
const forms = data._embedded?.compliance_forms || [];
allForms.push(...forms);

cursor = data.has_more ? data._links?.next?.href?.split('after_cursor=')[1]?.split('&')[0] : null;
} while (cursor);

// Generate analytics
const dashboard = {
total_forms: allForms.length,
by_state: {
INCOMPLETE: 0,
COMPLETE: 0,
EXPIRED: 0
},
by_type: {},
unique_merchants: new Set(),
overdue: 0,
expiring_soon: 0, // within 30 days
compliance_rate: 0
};

const now = new Date();
const thirtyDaysFromNow = new Date(now.getTime() + (30 * 24 * 60 * 60 * 1000));

allForms.forEach(form => {
// Count by state
dashboard.by_state[form.state]++;

// Count by type
dashboard.by_type[form.type] = (dashboard.by_type[form.type] || 0) + 1;

// Track merchants
dashboard.unique_merchants.add(form.linked_to);

// Count overdue
if (form.state === 'INCOMPLETE' && new Date(form.due_at) < now) {
dashboard.overdue++;
}

// Count expiring soon
if (form.state === 'COMPLETE') {
const validUntil = new Date(form.valid_until);
if (validUntil > now && validUntil <= thirtyDaysFromNow) {
dashboard.expiring_soon++;
}
}
});

// Calculate compliance rate
dashboard.compliance_rate = allForms.length > 0
? ((dashboard.by_state.COMPLETE / allForms.length) * 100).toFixed(2)
: 0;

dashboard.unique_merchants = dashboard.unique_merchants.size;

console.log('Compliance Dashboard:', dashboard);

return dashboard;
}

7. Export Forms to CSV

Export compliance forms for reporting:

async function exportComplianceFormsCSV(filters = {}) {
// Build query string
const params = new URLSearchParams();
if (filters.state) params.append('state', filters.state);
if (filters.linked_to) params.append('linked_to', filters.linked_to);
params.append('limit', '100');

const response = await fetch(
`https://api.ahrvo.network/payments/na/compliance_forms?${params}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const data = await response.json();
const forms = data._embedded?.compliance_forms || [];

// Build CSV
const headers = [
'Form ID',
'Merchant ID',
'Type',
'State',
'Created At',
'Due Date',
'Valid From',
'Valid Until',
'Signer Name',
'Signed At',
'Unsigned File',
'Signed File'
];

const rows = forms.map(form => [
form.id,
form.linked_to,
form.type,
form.state,
new Date(form.created_at).toLocaleDateString(),
new Date(form.due_at).toLocaleDateString(),
new Date(form.valid_from).toLocaleDateString(),
new Date(form.valid_until).toLocaleDateString(),
form.pci_saq_a?.name || '',
form.pci_saq_a?.signed_at ? new Date(form.pci_saq_a.signed_at).toLocaleDateString() : '',
form.unsigned_file || '',
form.signed_file || ''
]);

const csv = [
headers.join(','),
...rows.map(row => row.map(cell => `"${cell}"`).join(','))
].join('\n');

console.log(`Exported ${forms.length} forms to CSV`);

return csv;
}

8. Send Compliance Reminders

Notify merchants with incomplete or expiring forms:

async function sendComplianceReminders() {
// Find incomplete forms
const incomplete = await findIncompleteForms();

// Send reminders for overdue forms
for (const form of incomplete.overdue) {
await sendEmail(await getMerchantEmail(form.linked_to), {
subject: 'URGENT: Overdue Compliance Form',
template: 'compliance_overdue',
data: {
form_type: form.type,
due_date: form.due_at,
days_overdue: Math.floor((new Date() - new Date(form.due_at)) / (1000 * 60 * 60 * 24)),
unsigned_file: form.unsigned_file
}
});

console.log(`Sent overdue reminder to merchant ${form.linked_to}`);
}

// Send reminders for upcoming due forms
for (const form of incomplete.upcoming) {
const daysUntilDue = Math.ceil((new Date(form.due_at) - new Date()) / (1000 * 60 * 60 * 24));

if (daysUntilDue <= 7) { // Within 7 days
await sendEmail(await getMerchantEmail(form.linked_to), {
subject: 'Compliance Form Due Soon',
template: 'compliance_reminder',
data: {
form_type: form.type,
due_date: form.due_at,
days_until_due: daysUntilDue,
unsigned_file: form.unsigned_file
}
});

console.log(`Sent upcoming reminder to merchant ${form.linked_to}`);
}
}

// Send renewal reminders for expiring forms
const expiring = await findExpiringForms(30);

for (const form of expiring) {
await sendEmail(await getMerchantEmail(form.linked_to), {
subject: 'Compliance Form Expiring Soon',
template: 'compliance_expiring',
data: {
form_type: form.type,
valid_until: form.valid_until,
days_remaining: Math.ceil((new Date(form.valid_until) - new Date()) / (1000 * 60 * 60 * 24))
}
});

console.log(`Sent expiration reminder to merchant ${form.linked_to}`);
}
}

Query Parameters

ParameterTypeDescription
limitintegerNumber of results per page (default: 20, max: 100)
after_cursorstringCursor for forward pagination
before_cursorstringCursor for backward pagination
statestringFilter by state: INCOMPLETE, COMPLETE, or EXPIRED
linked_tostringFilter by merchant ID

Response Fields

FieldTypeDescription
_embedded.compliance_formsarrayArray of compliance form objects
has_morebooleanWhether more results exist
_links.nextobjectLink to next page (if has_more is true)
_links.prevobjectLink to previous page

Compliance Form Object

Each form in the array contains:

  • id - Form ID
  • created_at - Creation timestamp
  • state - INCOMPLETE, COMPLETE, or EXPIRED
  • type - Form type (e.g., PCI_SAQ_A)
  • linked_to - Merchant ID
  • linked_type - Entity type
  • due_at - Due date
  • valid_from - Validity start date
  • valid_until - Validity end date
  • unsigned_file - URL to unsigned form
  • signed_file - URL to signed form (if complete)
  • pci_saq_a - Signature details (if complete)

Best Practices

1. Use Filters to Reduce Data

Filter results to get only what you need:

// Good: Filter by state
const incompleteForms = await fetch(
'https://api.ahrvo.network/payments/na/compliance_forms?state=INCOMPLETE',
{ /* ... */ }
);

// Avoid: Fetching all and filtering client-side
// Only do this if you need all data for analytics

2. Paginate Large Result Sets

Use cursor pagination for large datasets:

async function getAllComplianceForms() {
const allForms = [];
let cursor = null;

do {
const url = cursor
? `https://api.ahrvo.network/payments/na/compliance_forms?after_cursor=${cursor}&limit=100`
: 'https://api.ahrvo.network/payments/na/compliance_forms?limit=100';

const response = await fetch(url, {
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
});

const data = await response.json();
allForms.push(...(data._embedded?.compliance_forms || []));

cursor = data.has_more ? data._links?.next?.href?.split('after_cursor=')[1]?.split('&')[0] : null;

} while (cursor);

return allForms;
}

3. Cache List Results

Cache to reduce API calls:

const listCache = {
data: null,
timestamp: 0,
ttl: 5 * 60 * 1000 // 5 minutes
};

async function getCachedComplianceList(filters = {}) {
const cacheKey = JSON.stringify(filters);

if (listCache.key === cacheKey &&
Date.now() - listCache.timestamp < listCache.ttl) {
return listCache.data;
}

const params = new URLSearchParams(filters);
const response = await fetch(
`https://api.ahrvo.network/payments/na/compliance_forms?${params}`,
{
method: 'GET',
headers: {
'Authorization': 'Basic ' + btoa('username:password'),
'Content-Type': 'application/json'
}
}
);

const data = await response.json();

listCache.data = data;
listCache.key = cacheKey;
listCache.timestamp = Date.now();

return data;
}

4. Monitor Compliance Regularly

Set up automated monitoring:

// Run daily
async function dailyComplianceCheck() {
const incomplete = await findIncompleteForms();
const expiring = await findExpiringForms(30);

const report = {
date: new Date().toLocaleDateString(),
incomplete_total: incomplete.all.length,
overdue: incomplete.overdue.length,
expiring_soon: expiring.length
};

// Alert if thresholds exceeded
if (report.overdue > 0 || report.expiring_soon > 5) {
await sendAlert({
type: 'compliance_alert',
report
});
}

console.log('Daily compliance check:', report);
}

5. Track Compliance Metrics

Monitor compliance rates over time:

async function trackComplianceMetrics() {
const dashboard = await generateComplianceDashboard();

await db.metrics.create({
date: new Date(),
total_forms: dashboard.total_forms,
compliance_rate: dashboard.compliance_rate,
incomplete: dashboard.by_state.INCOMPLETE,
complete: dashboard.by_state.COMPLETE,
expired: dashboard.by_state.EXPIRED,
overdue: dashboard.overdue,
expiring_soon: dashboard.expiring_soon
});

console.log('Metrics tracked:', dashboard);
}

Common Workflows

Weekly Compliance Report

async function generateWeeklyReport() {
const dashboard = await generateComplianceDashboard();
const incomplete = await findIncompleteForms();
const expiring = await findExpiringForms(30);

const report = {
week_ending: new Date().toLocaleDateString(),
summary: {
total_forms: dashboard.total_forms,
compliance_rate: `${dashboard.compliance_rate}%`,
unique_merchants: dashboard.unique_merchants
},
by_state: dashboard.by_state,
action_items: {
overdue_forms: incomplete.overdue.length,
expiring_within_30_days: expiring.length
}
};

// Send to compliance team
await sendEmail('compliance@company.com', {
subject: `Weekly Compliance Report - ${report.week_ending}`,
template: 'weekly_compliance_report',
data: report
});

console.log('Weekly report generated:', report);
}

Merchant Onboarding Compliance Check

async function checkMerchantCompliance(merchantId) {
const forms = await getMerchantForms(merchantId);

const isCompliant = forms.by_state.INCOMPLETE === 0 &&
forms.by_state.EXPIRED === 0;

if (!isCompliant) {
console.warn(`Merchant ${merchantId} is not compliant`);
console.warn('Incomplete:', forms.by_state.INCOMPLETE);
console.warn('Expired:', forms.by_state.EXPIRED);
} else {
console.log(`✓ Merchant ${merchantId} is compliant`);
}

return {
merchant_id: merchantId,
is_compliant: isCompliant,
forms: forms
};
}

Interactive API Reference