Skip to main content

Public API Documentation

Civic Review provides public API endpoints so you can build things that pull data from your Civic Review database.

Written by John Reynolds
Updated today

The Civic Review API allows you to read permit data from your Civic Review database and use it in your own external apps.

Requirements

First of all, you'll want to have your IT department or a developer help you with this. There are a lot of technical terms that require a basic understanding of http protocols.

You can view a few examples of how you could use the Civic Review API on the web here.

Authentication

API Keys

In order to access our API, you'll need to create an API key to prove who you are and give you access to certain information. You can create your API keys under Settings -> API Keys.

The best practice is to create only ONE API key per project. This way you can invalidate an API key if one project is compromised without having to invalidate all of your integrations. The name of the API key should be the name of the app that is using your API Key. For example, if you want to integrate with Survey123, you'd name the API key "Survey123".

API Environments

There are two API environments you can interact with:

  • TEST: Will return sample data, and will never do any real saving to the database. These api keys will have the word test in it. For example: cr_pk_test_t6hj345ktbn4j3ktrh4e.

  • LIVE: Will use real data. These api keys will have the word live in it. For example: cr_pk_live_t6hj345ktbn4j3ktrh4e.

Access to Permit Data

When using the API, our servers will return "default" properties for any permit requested. Default properties are the ones that are basically standard fields that all types of permits share. This include fields like dateApplied, applicationStatus, etc.

The meaty data associated with your permits is stored in the permit details (or inside the application form area). Because this data might include sensitive information or PII, you should take care with how this data is moved around.

Let's say you build a webpage that lists all your active building permits and you pull permit data in from Civic Review. This permit data might include personal information about the owner. If this request is done in the browser, behind the scenes, even if you don't SHOW all the personal info on the site, the data is still exposed. For this reason, our API's default behavior is to NOT provide access to field information.

This is great because you can have some API keys that provide more information than others, depending on where that data is moving around.

When is it Safe to Access Personal Information via the API?

In general terms, if you're pulling PII (read about this here), you should only do so from the server-side. Anything client-facing (in the browser) should only receive data that does not fall under PII. If data is sent to the browser, it should be done so in an area that is protected behind some sort of login, so that data is not exposed to the public. This might include things like a private google sheet, or, as mentioned 3rd party apps that require a login, such as Survey123.

Adding Field Access

Each API key must specify which field data it has access to. Our servers will only return data from field that are added to the list. You can specify which fields will be returned in the API Key settings. You can add/remove fields at any time once an API key is set up, so you don't need to get it right the first time.

Using an API Key

Every request to the API needs to include an authorization header with the API key provided as follows:

Authorization: Bearer cr_pk_live_samplekey

API Base URL

The base URL of the API is:

https://api.civicreview.com/public


GET /v1/permits/{permitId}

https://api.civicreview.com/public/v1/permits/{permitId}

Returns a single permit record.

URL Params

permitId

string required

The permit ID. See below how to get this.

Query Params

None.

Response

Returns the permit record, along with any form fields cleared for use by the API key. For an explanation of what the different permit fields are, please reach out to us at [email protected].

Example

curl -X GET "https://api.civicreview.com/public/v1/permits/596962be313220d698655966" \
-H "Authorization: Bearer cr_pk_live_samplekey" \
-H "Content-Type: application/json"

GET /v1/permits

https://api.civicreview.com/public/v1/permits

Returns an array of permits. For best performance, use query parameters to filter the results.

URL Params

None.

Query Params

Use these parameters to filter your results. You can combine multiple filters at once. When combined, ALL parameters must be satisfied for a permit to be included in the results. Some parameters have a dot in them. These parameters are NOT objects. For example, formData.dateSubmitted should be a whole string, so if you were to use it, the parameter would be ?latestTerm.isComplete=false.

Parameter

Type

Description

permitTypes

Array

Provide an array of Permit Type IDs to get only permits that belong to those permit types. You can find the Permit Type ID by looking at the URL when navigating to a Permit Type's main settings page.

​https://app.civicreview.com/permit-types/{permit_type_id}

permitNumber

Array

An array of permit numbers. Remember, permit numbers are not necessarily unique.

isActive

Boolean

true or false. You can choose to only get active permits (ones that haven't been archived or denied).

applicationStatus

Array

Possible statuses are:

  • INIT_PAYMENT

  • NEW

  • PRE_PAYMENT

  • DEPT_REVIEW

  • FINAL_REVIEW

  • FINAL_PAYMENT

  • COMPLETE

  • DENIED

renewalStatus

Array

Possible statuses are:

  • EMAIL

  • DATA_CONFIRMATION

  • QUESTIONNAIRE

  • SIGNATURE

  • DATA_APPROVAL

  • DEPT_REVIEW

  • FINAL_REVIEW

  • PAYMENT

  • OVERRIDE_INCOMPLETE

  • CLOSE_REQUEST

formData.dateSubmitted

Array

The array must have two date values, a start date and and end date to form a date range. If you want "everything before ____", the start date is still required, just set it to a long time ago.

Dates must be in ISO 8601 format (UTC time):

  • YYYY-MM-DDTHH:mm:ss.SSSZ

  • or YYYY-MM-DDTHH:mm:ssZ

For example. This date range returns all permits submitted in 2024. Notice the timezone offset is taken into account:

['2024-01-01T07:00:00.000Z', '2025-01-01T06:59:59.999Z']

latestTerm.isComplete

Boolean

true or false. A term is complete when the signature is collected (with an application or renewal) and the fees have been paid. See more below about the "latestTerm".

latestTerm.completedDate

Array

The array must have two date values to form a date range.

Dates must be in ISO 8601 format (UTC time). For more info about this format, see formData.dateSubmitted.

latestTerm.begDate

Array

The start date of a term. The array must have two date values to form a date range.

Dates must be in ISO 8601 format (UTC time). For more info about this format, see formData.dateSubmitted.

latestTerm.endDate

Array

The end date of a term. The array must have two date values to form a date range.

Dates must be in ISO 8601 format (UTC time). For more info about this format, see formData.dateSubmitted.

About the latestTerm

Since a permit can have multiple terms, filtering by any one of the terms is difficult. But you can, however, filter by the latest term. For example, if you wanted to filter out only expired business licenses, you would use the latestTerm.endDate filter. You'll still get all the terms in the results. You can read more about terms here.

Response

Returns the permit record, along with any form fields cleared for use by the API key. For an explanation of what the different permit fields are, please reach out to us at [email protected].

Examples

Array values can be represented in the following two ways. Consider:

permitTypes: [5924ae0daa6ed9000cf6315a,5e8ca1d443df4200108c7e66,58f62c26e74876000c70e43b]

  • permitTypes[]=5924ae0daa6ed9000cf6315a&permitTypes[]=5e8ca1d443df4200108c7e66&permitTypes[]=58f62c26e74876000c70e43b

  • permitTypes=5924ae0daa6ed9000cf6315a&permitTypes=5e8ca1d443df4200108c7e66&permitTypes=58f62c26e74876000c70e43b

GET permits that belong to Permit Types

curl -X GET "https://api.civicreview.com/public/v1/permits?permitTypes[]=5924ae0daa6ed9000cf6315a&permitTypes[]=5e8ca1d443df4200108c7e66&permitTypes[]=58f62c26e74876000c70e43b" \
-H "Authorization: Bearer cr_pk_live_samplekey" \
-H "Content-Type: application/json"

GET active permits

curl -X GET "https://api.civicreview.com/public/v1/permits?isActive=true" \
-H "Authorization: Bearer cr_pk_live_samplekey" \
-H "Content-Type: application/json"

GET new permit applications awaiting payment

curl -X GET "https://api.civicreview.com/public/v1/permits?applicationStatus[]=INIT_PAYMENT&applicationStatus[]=PRE_PAYMENT&applicationStatus[]=FINAL_PAYMENT" \
-H "Authorization: Bearer cr_pk_live_samplekey" \
-H "Content-Type: application/json"

GET permits that expired in October of 2025 and have not started renewal

This one is a little trickier. You'd probably only want to include active permits that have been approved and expire in October. Otherwise you could end up with applications that were never approved or that have been denied. For this reason, we need to combine the applicationStatus, isActive, and latestTerm.endDate filters.

curl -X GET "https://api.civicreview.com/public/v1/permits?isActive=true&applicationStatus[]=COMPLETE&latestTerm.endDate[]=2025-10-01T07:00:00.000Z&latestTerm.endDate[]=2025-11-01T06:59:59.999Z" \
-H "Authorization: Bearer cr_pk_live_samplekey" \
-H "Content-Type: application/json"

Did this answer your question?