This table is populated in real time from the Civic Review API.
Loading business licenses...
licenses found
| Business Name | Address | City | State | Zip | Date Submitted | Status |
|---|
Here's the JavaScript and HTML used to build this example.
JavaScript
const API_BASE = 'https://api.civicreview.com/public/v1';
const API_KEY = 'YOUR_API_KEY';
// Field IDs for the data we want to display
const FIELD_IDS = {
businessAddress: '5f15d98fc41f2c00103fd476',
city: '5f15d99bc41f2c00103fd478',
state: '5f15d9a6c41f2c00103fd479',
zip: '5f15d9adc41f2c00103fd47a'
};
async function fetchBusinessLicenses() {
const params = new URLSearchParams({
isActive: 'true',
'permitTypes[]': '58f62c26e74876000c70e43b',
'formData.dateSubmitted[]': '2025-01-01T07:00:00.000Z',
});
// URLSearchParams overwrites duplicate keys, so append the second date
params.append('formData.dateSubmitted[]', '2025-12-31T06:59:59.999Z');
const response = await fetch(`${API_BASE}/permits?${params}`, {
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`API request failed: ${response.status} ${response.statusText}`);
}
return response.json();
}
function getFieldValue(permit, fieldId) {
const field = permit.formData?.fields?.find(f => f.formField === fieldId);
return field?.value || '—';
}
function formatDate(dateString) {
if (!dateString) return '—';
return new Date(dateString).toLocaleDateString('en-US', {
year: 'numeric', month: 'short', day: 'numeric'
});
}
function renderTable(permits) {
const tbody = document.getElementById('table-body');
document.getElementById('count').textContent = permits.length;
tbody.innerHTML = permits.map(permit => `
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-sm font-medium">${permit.entityName || '—'}</td>
<td class="px-4 py-3 text-sm">${getFieldValue(permit, FIELD_IDS.businessAddress)}</td>
<td class="px-4 py-3 text-sm">${getFieldValue(permit, FIELD_IDS.city)}</td>
<td class="px-4 py-3 text-sm">${getFieldValue(permit, FIELD_IDS.state)}</td>
<td class="px-4 py-3 text-sm">${getFieldValue(permit, FIELD_IDS.zip)}</td>
<td class="px-4 py-3 text-sm">${formatDate(permit.formData?.dateSubmitted)}</td>
<td class="px-4 py-3 text-sm">
<span class="inline-flex items-center rounded-full bg-green-50 px-2 py-1 text-xs font-medium text-green-700">
${permit.applicationStatus}
</span>
</td>
</tr>
`).join('');
document.getElementById('loading').classList.add('hidden');
document.getElementById('results').classList.remove('hidden');
}
fetchBusinessLicenses()
.then(renderTable)
.catch(err => {
document.getElementById('loading').classList.add('hidden');
document.getElementById('error').classList.remove('hidden');
document.getElementById('error-message').textContent = err.message;
});
HTML
<div id="loading">Loading business licenses...</div>
<div id="error" class="hidden">
<p id="error-message"></p>
</div>
<div id="results" class="hidden">
<p><span id="count"></span> licenses found</p>
<table>
<thead>
<tr>
<th>Business Name</th>
<th>Address</th>
<th>City</th>
<th>State</th>
<th>Zip</th>
<th>Date Submitted</th>
<th>Status</th>
</tr>
</thead>
<tbody id="table-body"></tbody>
</table>
</div>