Introduction
The ISO Amp API is a RESTful API for integrating with the ISO Amp tool. The examples use the domain example.com
. Replace example.com
with your ISO Amp domain.
Authentication
To authorize, use this code:
curl "api_endpoint_here" \
-H "Authorization: 01234567890abcdef"
Make sure to replace
01234567890abcdef
with your API key.
ISO Amp uses API keys to allow access to the API. You can register a API key in the admin panel.
ISO Amp expects the API key to be included in all API requests to the server in a header that looks like the following:
Authorization: 01234567890abcdef
Merchant Application Integration
Proposals can be sent to your own backend system with a single click. Here is an example flow for a merchant application:
- User goes through quote tool and creates proposal.
- User clicks on "Start Application" button.
- The user's browser follows the link to your backend system and includes the proposal ID in the URL.
- Your backend system uses the proposal API to fetch the proposal.
- Your backend system creates a merchant services application with the relevant information from the proposal.
- Your backend system redirects the user's browser to the prefilled online application.
Proposal Handoff Links
A proposal handoff link is the entity that creates a button on the proposal screen. The label of the button and the destination URL template is all that is required. Proposal handoff links are created in the Admin page in the Developer section.
Attribute | Type | Description |
---|---|---|
Agent View | boolean | Button will be displayed on the agent proposal view. |
Label | string | The text of the button |
Merchant View | boolean | Button will be displayed on the merchant proposal view. |
URL Template | string | URL template for the destination of the button. {proposal_id} will be replaced with the actual proposal ID. |
Statement Analysis
Submitting a statement for analysis is a 3-step process.
- Create the statement analysis request (
POST /api/statement_analyses
). - Upload the statement file(s) (
POST /api/statement_analyses/{id}/files
). - Start the statement analysis (
POST /api/statement_analyses/{id}/start
).
Create a Statement Analysis
curl https://example.com/api/statement_analyses \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X POST \
-d '{ "userId": 12345, "name": "Sept 2021", "merchantName": "Fancy Burgers" }'
The above command returns JSON structured like this:
{
"id": "cc945b9a-47e5-4198-a3b8-b5ef1f6ed734"
}
HTTP Request
POST https://example.com/api/statement_analyses
Required Attributes
Attribute | Type | Description |
---|---|---|
userId | int32 | Analysis is for this user ID |
name | string | Name for this statement analysis (e.g. the statement date) |
merchantName | string | Name of business |
Allowed Attributes
Attribute | Type | Default | Description |
---|---|---|---|
mcc | string | None | Merchant Category Code |
notes | string | None | Any extra notes to attach to this analysis |
Upload a Statement File
After the statement analysis is created by the POST https://example.com/api/statement_analyses
API the statement file(s) must be uploaded. The file contents must be the body of the POST
. This API may be called multiple times to include multiple files (e.g. a processing statement and an American Express statement for the same month). Do not include multiple months or locations in the same analysis.
curl 'https://example.com/api/statement_analyses/0b8f40cb-9be1-4d93-8b2a-e36b97c4be45/files?filename=statement.pdf' \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/pdf' \
-X POST \
--data-binary @statement.pdf
The above command returns a
200 OK
on success with no response body.
HTTP Request
POST https://example.com/api/statement_analyses/{id}/files
Required HTTP Headers
Header | Description |
---|---|
Content-Length | Size of uploaded file |
Content-Type | MIME type of uploaded file. Must be application/pdf . |
Required Query Parameters
Attribute | Type | Description |
---|---|---|
filename | string | Name of uploaded file |
Start statement analysis
After all required files have been uploaded this API should be called to start the statement analysis.
curl https://example.com/api/statement_analyses/0b8f40cb-9be1-4d93-8b2a-e36b97c4be45/start \
-H 'Authorization: 01234567890abcdef' \
-X POST
The above command returns a
202 Accepted
on success with no response body.
HTTP Request
POST https://example.com/api/statement_analyses/{id}/start
Estimate Statement Summary
The estimate statement summary API can be used to quickly estimate fees from only a statement summary.
curl https://example.com/api/estimate_statement_summary \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X POST \
-d '{ "merchantActivity": [ {"type": "vs", "volume": 8000, "transactions": 100}, {"type": "mc", "volume": 2000, "transactions": 30} ], "totalCurrentFees": 320 }'
The above command returns JSON structured like this:
{"vmdInterchange":"151.49","vmdCardBrandFees":"4","amexOptBlue":null,"pinDebitNetworkFees":null,"scheduleACost":"14.6","margin":"0.01499"}
This endpoint estimates summary passthrough fees, processor costs, and markup.
HTTP Request
POST https://example.com/api/estimate_statement_summary
Request Attributes
Attribute | Type | Description |
---|---|---|
merchantActivity | array of merchant activities | List of merchant activities by card type and brand |
totalCurrentFees | numeric string | Total fees the merchant is currently paying |
Merchant Activity Attributes
Attribute | Type | Description |
---|---|---|
type | string | Type of activity |
volume | numeric string | Volume of merchant activity in dollars |
transactions | integer | Number of transactions |
Merchant Activity Types
Type | Description |
---|---|
vmd | Visa, Mastercard, and Discover combined |
vs | Visa credit and check |
vs_credit | Visa credit |
vs_check | Visa check |
mc | Mastercard credit and check |
mc_credit | Mastercard credit |
mc_check | Mastercard check |
ds | Discover credit and check |
ds_credit | Discover credit |
ds_check | Discover check |
amex | American Express |
pin_debit | PIN Debit |
Response Attributes
Attribute | Type | Description |
---|---|---|
vmdInterchange | numeric string | Estimated Visa, Mastercard, and Discover interchange fees |
vmdCardBrandFees | numeric string | Estimated Visa, Mastercard, and Discover card brand fees |
amexOptBlue | numeric string | Estimated American Express Opt Blue fees |
pinDebitNetworkFees | numeric string | Estimated PIN debit network fees |
scheduleACost | numeric string | Estimated Schedule A costs |
margin | numeric string | Estimated margin rate |
Proposals
Proposal Definition
Attribute | Type | Description |
---|---|---|
creationTime | integer | When the proposal was created in Unix time (i.e. number of seconds since 1970-01-01 00:00:00 UTC) |
id | uuid | Unique identifier |
merchantActivities | array | List of merchant activity records |
programFeatures | array | List of selected program features |
programId | text | ID of the proposed program |
fees | array | List of fees proposed and current |
prospectId | uuid | ID of the prospect this proposal belongs to |
currentProcessor | string | Name of current processor |
programId
can be set when defining a program. It may be null
if the proposal does not have a program assigned to it or if the program originally assigned has been deleted.
currentProcessor
is only known when the proposal is created by analyzing a statement. In addition, the processor can only be accurately determined on some statement types.
Merchant Activity Definition
Attribute | Type | Description |
---|---|---|
name | string | Name (typically from card type summary table) |
typeId | string | Type of activity (e.g. "vs", "mc", "ds", etc.) |
volume | numeric string | Volume in dollars |
transactions | numeric string | Number of transactions |
Program Feature Definition
Attribute | Type | Description |
---|---|---|
id | string | Unique identifier |
name | string | Name of program feature |
Fee Definition
Attribute | Type | Description |
---|---|---|
name | string | Human-readable name of fee |
programFeeId | string | ID of fee defined by program |
quantity | numeric string | Quantity to which the fee rate will be applied |
proposedRate | numeric string | The rate proposed to charge the merchant |
proposedMonthlyAmount | numeric string | The amount the merchant will pay per month |
currentRate | numeric string | The rate the merchant is currently paying |
currentMonthlyAmount | numeric string | The amount the merchant is currently paying per month |
programFeeId
can be set when defining a program.
It is possible for there to a fee with a proposedMonthlyAmount
of 0
because of merchant activity or selected program features. For example, a monthly PIN debit fee with an proposedRate
of 9.95
may be present but have a proposedMonthlyAmount
of 0
if there are no PIN debit transactions.
currentRate
is the effective current rate based on quantity
and currentMonthlyAmount
. This may sometimes vary from the rate actually displayed on the statement. For example, given a VMD Per Item fee, quantity
will be the total number of Visa, Mastercard, and Discover transactions. This information can be extracted from the card type summary table, the interchange table, and processor fees. Unfortunately, statements often contain information in each section that contradicts the other sections (e.g. the card type summary table shows there are 60 VMD transactions, the interchange table shows 58 VMD transactions, and a processor VMD Per Item fee claims there were 62 transactions). In addition, sometimes an individual fee line on a statement has a total does not equal the product of the quantity and rate. This can be due to rounding issues but often has no visible explanation. But in any case, to provide an apples-to-apples rate comparison, the currentRate
is calculated as currentMonthlyAmount / quantity
.
Get All Proposals
curl "https://example.com/api/proposals" \
-H "Authorization: 01234567890abcdef"
The above command returns JSON structured like this:
{
"object": "list",
"hasMore": true,
"data": [
{
"id": "c9d21a63-c3c3-44f8-acec-e7374cce186b",
"fees": [
{
"id": 12345,
"name": "VMD Card Brand",
"quantity": "68.67",
"currentRate": "1",
"programFeeId": "VMD Card Brand",
"proposedRate": "1",
"currentMonthlyAmount": "68.67",
"proposedMonthlyAmount": "68.67"
},
{
"id": 12346,
"name": "VMD Interchange",
"quantity": "882.01",
"currentRate": "1.0",
"programFeeId": "VMD Interchange",
"proposedRate": "1.0",
"currentMonthlyAmount": "882.01",
"proposedMonthlyAmount": "882.01"
},
{
"id": 12347,
"name": "VMD Per Item",
"quantity": "45",
"currentRate": "0.1",
"programFeeId": "VMD Per Item",
"proposedRate": "0.05",
"currentMonthlyAmount": "4.5",
"proposedMonthlyAmount": "2.25"
},
{
"id": 12348,
"name": "VMD Volume",
"quantity": "47265.32",
"currentRate": "0.005",
"programFeeId": "VMD Volume",
"proposedRate": "0.004",
"currentMonthlyAmount": "236.33",
"proposedMonthlyAmount": "189.06"
},
{
"id": 12349,
"name": "PCI Monthly",
"quantity": "1",
"currentRate": "5",
"programFeeId": "PCI Monthly",
"proposedRate": "10",
"currentMonthlyAmount": "5.00",
"proposedMonthlyAmount": "10.00"
}
],
"object": "proposal",
"programId": "d9feedfa-62ab-4ba1-954c-4deca6fe2013",
"prospectId": "214c3843-1484-4f2d-bea9-8398c9289924",
"creationTime": 165164512,
"programFeatures": [],
"merchantActivities": [
{
"name": "DISCOVER",
"typeId": "ds",
"volume": "855.46",
"transactions": "5"
},
{
"name": "MASTERCARD",
"typeId": "mc",
"volume": "12482.36",
"transactions": "12"
},
{
"name": "VISA",
"typeId": "vs",
"volume": "33927.50",
"transactions": "28"
}
]
}
]
}
This endpoint retrieves all proposals. If hasMore
is true
then more proposals are available which can be fetched using the startAfterId
query parameter.
HTTP Request
GET https://example.com/api/proposals
Query Parameters
Parameter | Default | Description |
---|---|---|
limit | 10 | Limit the number of proposals returned (valid values are integers 1 to 100). |
startAfterId | None | Only include proposals created after proposal with this ID (must be UUID). |
Get a Specific Proposal
curl https://example.com/api/proposals/a7d07942-a31a-4b45-b55a-48d40d116f07 \
-H 'Authorization: 01234567890abcdef'
The above command returns JSON structured like this:
{
"id": "c9d21a63-c3c3-44f8-acec-e7374cce186b",
"fees": [
{
"id": 12345,
"name": "VMD Card Brand",
"quantity": "68.67",
"currentRate": "1",
"programFeeId": "VMD Card Brand",
"proposedRate": "1",
"currentMonthlyAmount": "68.67",
"proposedMonthlyAmount": "68.67"
},
{
"id": 12346,
"name": "VMD Interchange",
"quantity": "882.01",
"currentRate": "1.0",
"programFeeId": "VMD Interchange",
"proposedRate": "1.0",
"currentMonthlyAmount": "882.01",
"proposedMonthlyAmount": "882.01"
},
{
"id": 12347,
"name": "VMD Per Item",
"quantity": "45",
"currentRate": "0.1",
"programFeeId": "VMD Per Item",
"proposedRate": "0.05",
"currentMonthlyAmount": "4.5",
"proposedMonthlyAmount": "2.25"
},
{
"id": 12348,
"name": "VMD Volume",
"quantity": "47265.32",
"currentRate": "0.005",
"programFeeId": "VMD Volume",
"proposedRate": "0.004",
"currentMonthlyAmount": "236.33",
"proposedMonthlyAmount": "189.06"
},
{
"id": 12349,
"name": "PCI Monthly",
"quantity": "1",
"currentRate": "5",
"programFeeId": "PCI Monthly",
"proposedRate": "10",
"currentMonthlyAmount": "5.00",
"proposedMonthlyAmount": "10.00"
}
],
"object": "proposal",
"programId": "d9feedfa-62ab-4ba1-954c-4deca6fe2013",
"prospectId": "214c3843-1484-4f2d-bea9-8398c9289924",
"creationTime": 165164512,
"programFeatures": [],
"merchantActivities": [
{
"name": "DISCOVER",
"typeId": "ds",
"volume": "855.46",
"transactions": "5"
},
{
"name": "MASTERCARD",
"typeId": "mc",
"volume": "12482.36",
"transactions": "12"
},
{
"name": "VISA",
"typeId": "vs",
"volume": "33927.50",
"transactions": "28"
}
]
}
This endpoint retrieves a specific proposal.
HTTP Request
GET https://example.com/api/proposals/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the proposal to retrieve |
Change Proposal Program
curl https://example.com/api/proposals/a7d07942-a31a-4b45-b55a-48d40d116f07/program \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X POST \
-d '{"programId": "interchangeplus"}'
The above command does not return a response body.
This endpoint changes the program used by the proposal.
HTTP Request
POST https://example.com/api/proposals/{id}/program
URL Parameters
Parameter | Description |
---|---|
id | The ID of the proposal to update |
Attributes
Attribute | Type | Description |
---|---|---|
programId | string | ID of program to use |
Program IDs can be viewed and changed in the Admin -> Programs -> Program Details page.
Change Proposal Template
curl https://example.com/api/proposals/a7d07942-a31a-4b45-b55a-48d40d116f07/template \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X POST \
-d '{"templateId": "b774aebd-cdbd-4eff-8c57-bf2c6b843bd3"}'
The above command does not return a response body.
This endpoint changes the template used by the proposal.
HTTP Request
POST https://example.com/api/proposals/{id}/template
URL Parameters
Parameter | Description |
---|---|
id | The ID of the proposal to update |
Attributes
Attribute | Type | Description |
---|---|---|
templateId | UUID | ID of proposal template to use |
Template IDs can be viewed in the Admin -> Proposal Templates -> Details page.
Update Fee Rate
curl https://example.com/api/proposal_fees/12345 \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X POST \
-d '{"rate": "0.005"}'
The above command does not return a response body.
This endpoint changes the proposed rate of a proposal fee.
HTTP Request
PATCH https://example.com/api/proposal_fees/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the proposal fee to update |
Attributes
Attribute | Type | Description |
---|---|---|
rate | numeric string | Rate that will be charged |
Download Proposal as PDF
curl https://example.com/api/proposals/a7d07942-a31a-4b45-b55a-48d40d116f07/document \
-H 'Authorization: 01234567890abcdef' \
-H 'Accept: application/pdf' \
--output document.pdf
The above command returns a PDF file and saves the results.
This endpoint changes the template used by the proposal.
HTTP Request
GET https://example.com/api/proposals/{id}/document
The Accept
header must be set to application/pdf
.
URL Parameters
Parameter | Description |
---|---|
id | The ID of the proposal to download |
Clone a Proposal
This endpoint creates a clone of a proposal.
HTTP Request
POST https://example.com/api/proposals/{id}/clone
curl https://example.com/api/proposals/a7d07942-a31a-4b45-b55a-48d40d116f07/clone \
-X POST \
-H 'Authorization: 01234567890abcdef' \
The above command returns JSON structured like this:
{
"id": "33ebe2d9-a717-4507-9933-fbc455748c69",
}
Create a Simple Proposal
curl https://example.com/api/proposals/simple \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X POST \
-d '{"prospectId": "9136dff2-6a30-48a5-8d8c-6a712ac89a3e", "totalVolume": 20000, "numTransactions": 100, "totalFees": "450"}'
The above command returns JSON structured like this:
{
"id": "33ebe2d9-a717-4507-9933-fbc455748c69",
}
This endpoint creates a simple proposal. This corresponds to the standard / simple form in the quote tool.
HTTP Request
POST https://example.com/api/proposals/simple
Attributes
Attribute | Type | Description |
---|---|---|
avgTicket | numeric string | Average VMD transaction amount in dollars |
numTransactions | numeric string | Number of VMD transactions |
preferredProgramId | text | ID of program to propose if possible |
prospectId | uuid | ID of prospect to create proposal for |
totalFees | numeric string | The total fees being paid now in dollars |
totalVolume | numeric string | Total VMD volume in dollars |
prospectId
and totalVolume
are required along with avgTicket
or numTransactions
.
Prospects
Prospect Definition
Attribute | Type | Description |
---|---|---|
business_name | string | Name of business |
contact_name | string | Name of contact at business |
created_at | timestamp | When the user was created formatted in ISO8601 |
Email address | ||
id | uuid | Unique identifier |
phone | string | Phone number |
prospect_stage_id | uuid | Prospect Stage ID |
source_type | string | Source of prospect |
user_id | uuid | User ID that owns prospect |
Get All Prospects
curl "https://example.com/api/v1/prospects" \
-H "Authorization: 01234567890abcdef"
The above command returns JSON structured like this:
{
"object": "list",
"data": [
{
"id": "0e68f57d-e361-4ea1-a827-0ce6256adf77",
"business_name": "Sal's Subs",
"contact_name": "Sal",
"phone": "555-5555",
"email": "sal@example.com",
"source_type": "in-person",
"user_id": "c742ce38-daa2-4011-a9b1-c85459186436",
"merchant_type_id": "9cd01d9c-4994-48b1-8246-9ecde769ae7c",
"prospect_stage_id": "7365ec0e-0aab-406c-b54e-3c6ed9f483d3",
"created_at": "2019-03-25T16:30:45.941-04:00",
"object": "prospect"
},
{
"id": "ab593f14-f2de-4ae0-a260-d1ac28d4badf",
"business_name": "Acme Food Stuffs",
"contact_name": "Phil",
"phone": "555-5555",
"email": "phil@example.com",
"source_type": "web",
"user_id": "c742ce38-daa2-4011-a9b1-c85459186436",
"merchant_type_id": "7447c292-332b-4c36-86a1-aa5ba256a4e8",
"prospect_stage_id": "1ae64c8a-66be-42f9-902c-5dc92bb70f3b",
"created_at": "2019-03-25T16:26:54.944-04:00",
"object": "prospect"
}
]
}
This endpoint retrieves all prospects sorted by created_at
ascending.
HTTP Request
GET https://example.com/api/v1/prospects
Query Parameters
Parameter | Default | Description |
---|---|---|
limit | 10 | Limit the number of prospects returned (valid values are integers 1 to 100). |
start_after_id | None | Only include prospects created after user with this ID (must be UUID). |
Get a Specific Prospect
curl https://example.com/api/v1/prospects/ab593f14-f2de-4ae0-a260-d1ac28d4badf \
-H 'Authorization: 01234567890abcdef'
The above command returns JSON structured like this:
{
"id": "ab593f14-f2de-4ae0-a260-d1ac28d4badf",
"business_name": "Acme Food Stuffs",
"contact_name": "Phil",
"phone": "555-5555",
"email": "phil@example.com",
"source_type": "web",
"user_id": "c742ce38-daa2-4011-a9b1-c85459186436",
"merchant_type_id": "7447c292-332b-4c36-86a1-aa5ba256a4e8",
"prospect_stage_id": "1ae64c8a-66be-42f9-902c-5dc92bb70f3b",
"created_at": "2019-03-25T16:26:54.944-04:00",
"object": "prospect"
}
This endpoint retrieves a specific prospect.
HTTP Request
GET https://example.com/api/v1/prospect/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the prospect to retrieve |
Create a Prospect
curl https://example.com/api/v1/prospects \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X POST \
-d '{"user_id": "c742ce38-daa2-4011-a9b1-c85459186436", "merchant_type_id": "196a094a-16a4-4fda-8007-9300ef9c5cf8", "prospect_stage_id": "1ae64c8a-66be-42f9-902c-5dc92bb70f3b", "business_name": "Fancy Burgers", "contact_name": "Sam", "phone": "555-5555", "email": "sam@example.com", "source_type": "search engine"}'
The above command returns JSON structured like this:
{
"id": "73458508-0ef5-4abb-9715-ceed559583f6",
"business_name": "Fancy Burgers",
"contact_name": "Sam",
"phone": "555-5555",
"email": "sam@example.com",
"source_type": "search engine",
"user_id": "c742ce38-daa2-4011-a9b1-c85459186436",
"merchant_type_id": "196a094a-16a4-4fda-8007-9300ef9c5cf8",
"prospect_stage_id": "1ae64c8a-66be-42f9-902c-5dc92bb70f3b",
"created_at": "2019-03-25T16:48:21.543-04:00",
"object": "prospect"
}
This endpoint creates a prospect.
HTTP Request
POST https://example.com/api/v1/users
Required Attributes
Attribute | Type | Description |
---|---|---|
prospect_stage_id | uuid | Prospect Stage ID |
source_type | string | Source of prospect |
user_id | uuid | User ID that owns prospect |
Allowed Attributes
Attribute | Type | Default | Description |
---|---|---|---|
business_name | string | None | Name of business |
contact_name | string | None | Name of contact at business |
None | Email address | ||
phone | string | None | Phone number |
Update a Specific Prospect
curl https://example.com/api/v1/prospects/73458508-0ef5-4abb-9715-ceed559583f6 \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X PATCH \
-d '{"email": "john@example.com"}'
The above command returns JSON structured like this:
{
"id": "73458508-0ef5-4abb-9715-ceed559583f6",
"business_name": "Fancy Burgers",
"contact_name": "Sam",
"phone": "555-5555",
"email": "john@example.com",
"source_type": "search engine",
"user_id": "c742ce38-daa2-4011-a9b1-c85459186436",
"merchant_type_id": "196a094a-16a4-4fda-8007-9300ef9c5cf8",
"prospect_stage_id": "1ae64c8a-66be-42f9-902c-5dc92bb70f3b",
"created_at": "2019-03-25T16:48:21.543-04:00",
"object": "prospect"
}
This endpoint updates a prospect.
HTTP Request
PATCH https://example.com/api/v1/prospects/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the prospect to update |
Allowed Attributes
Attribute | Type | Description |
---|---|---|
business_name | string | Name of business |
contact_name | string | Name of contact at business |
Email address | ||
phone | string | Phone number |
prospect_stage_id | uuid | Prospect Stage ID |
source_type | string | Source of prospect |
user_id | uuid | User ID that owns prospect |
Delete a Specific Prospect
curl https://example.com/api/v1/prospects/73458508-0ef5-4abb-9715-ceed559583f6 \
-H 'Authorization: 01234567890abcdef' \
-X DELETE
The above command does not return a response body.
This endpoint deletes a specific prospect.
HTTP Request
DELETE https://example.com/api/v1/prospects/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the prospect to delete |
Prospect Stages
Prospect Stage Definition
Attribute | Type | Description |
---|---|---|
id | uuid | Unique identifier |
name | string | Name |
Get All Prospect Stages
curl "https://example.com/api/prospect_stages" \
-H "Authorization: 01234567890abcdef"
The above command returns JSON structured like this:
{
"object": "list",
"data": [
{
"id": "1ae64c8a-66be-42f9-902c-5dc92bb70f3b",
"name": "Prospect",
"object": "prospect_stage"
},
{
"id": "2bb0ca43-b47a-408d-a48c-322ad3453905",
"name": "Quoted",
"object": "prospect_stage"
},
{
"id": "6820bc00-2aaa-472f-bda7-eeb64c9c5dbd",
"name": "Closed-Yes",
"object": "prospect_stage"
},
{
"id": "7365ec0e-0aab-406c-b54e-3c6ed9f483d3",
"name": "Contacted",
"object": "prospect_stage"
},
{
"id": "944e129f-635c-4a16-b9cd-0d6965b2b1fa",
"name": "Closed-No",
"object": "prospect_stage"
}
]
}
This endpoint retrieves all merchant types.
HTTP Request
GET https://example.com/api/prospect_stages
Get a Specific Prospect Stage
curl https://example.com/api/prospect_stages/944e129f-635c-4a16-b9cd-0d6965b2b1fa \
-H 'Authorization: 01234567890abcdef'
The above command returns JSON structured like this:
{
"id": "944e129f-635c-4a16-b9cd-0d6965b2b1fa",
"name": "Closed-No",
"object": "prospect_stage"
}
This endpoint retrieves a specific prospect stage.
HTTP Request
GET https://example.com/api/prospect_stages/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the prospect stage to retrieve |
Users
User Definition
Attribute | Type | Description |
---|---|---|
admin | bool | Is user an administrator |
creationTime | integer | Unix time (i.e. number of seconds since 1970-01-01 00:00:00 UTC) |
Email address | ||
id | integer | Unique identifier |
name | string | Name |
userName | string | User name (may be used for vanity quote URL) |
In addition, a user's password may be assigned on creation or reset later via the API. The password is securely digested and cannot be read via the API. However, it is preferable to use single sign-on rather than managing passwords via the API.
Get All Users
curl "https://example.com/api/users" \
-H "Authorization: 01234567890abcdef"
The above command returns JSON structured like this:
{
"object": "list",
"data": [
{
"id": "12345",
"email": "john@example.com",
"userName": "john",
"name": "John Doe",
"admin": false,
"object": "user",
"creationTime": 1587745044
},
{
"id": "67890",
"email": "jane@example.com",
"userName": "jane",
"name": "Jane Doe",
"admin": false,
"object": "user",
"creationTime": 1573666167
},
]
}
This endpoint retrieves all users sorted by creationTime
ascending. This endpoint is paginated. To fetch all records it is necessary to make multiple requests where the query parameter startAfterId
is the ID of the last record retrieved on the previous request. This must be done until a response is received where the data array is empty.
HTTP Request
GET https://example.com/api/users
Query Parameters
Parameter | Default | Description |
---|---|---|
limit | 10 | Limit the number of users returned (valid values are integers 1 to 100). |
startAfterId | None | Only include users created after user with this ID. |
Get a Specific User
curl https://example.com/api/users/12345 \
-H 'Authorization: 01234567890abcdef'
The above command returns JSON structured like this:
{
"id": "12345",
"email": "jane@example.com",
"userName": "jane",
"name": "Jane Doe",
"admin": false,
"object": "user",
"creationTime": 1587745044
}
This endpoint retrieves a specific user.
HTTP Request
GET https://example.com/api/users/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the user to retrieve |
Create a User
curl https://example.com/api/users \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X POST \
-d '{"email": "john@example.com", "userName": "john", "name": "John Smith", "admin": "false"}'
The above command returns JSON structured like this:
{
"id": "12345",
"email": "john@example.com",
"userName": "john",
"name": "John Smith",
"admin": false,
"object": "user",
"creationTime": 1587745044
}
This endpoint creates a user. As an alternative, single sign-on can be configured to create users on first sign-on.
HTTP Request
POST https://example.com/api/users
Required Attributes
Attribute | Type | Description |
---|---|---|
Email address | ||
name | string | Name |
userName | string | User name (must match this regexp: /\A[a-z][a-z0-9-]*\z/ ) |
Allowed Attributes
Attribute | Type | Default | Description |
---|---|---|---|
admin | bool | false | Is user an administrator |
password | string | Unguessable random string | Login password |
Update a Specific User
curl https://example.com/api/users/12345 \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X PATCH \
-d '{"email": "john@example.com", "userName": "john", "name": "John Smith", "admin": "false"}'
The above command returns JSON structured like this:
{
"id": "12345",
"email": "john@example.com",
"userName": "john",
"name": "John Smith",
"admin": false,
"object": "user",
"creationTime": 1587745044
}
This endpoint updates a user.
HTTP Request
PATCH https://example.com/api/users/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the user to update |
Allowed Attributes
Attribute | Type | Description |
---|---|---|
admin | bool | Is user an administrator |
Email address | ||
name | string | Name |
password | string | Login password |
userName | string | User name (must match this regexp: /\A[a-z][a-z0-9-]*\z/ ) |
Delete a Specific User
curl https://example.com/api/users/12345 \
-H 'Authorization: 01234567890abcdef' \
-X DELETE
The above command does not return a response body.
This endpoint deletes a specific user.
HTTP Request
DELETE https://example.com/api/users/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the user to delete |
Events
Event are created when something of note happens such as a statement analysis being completed. They can be pulled from the events API or pushed via webhook.
Event Definition
Attribute | Type | Description |
---|---|---|
data | object | Event data - see below for possible formats |
id | uuid | Unique identifier |
time | integer | Unix time (i.e. number of seconds since 1970-01-01 00:00:00 UTC) |
type | string | Event type - see below for possible values |
analysis.requested
A statement analysis was requested.
Attribute | Type | Description |
---|---|---|
statementAnalysisId | uuid | ID of the statement analysis |
agentId | integer | ID of the requesting agent |
name | string | Name of the statement analysis |
analysis.completed
A statement analysis was completed.
Attribute | Type | Description |
---|---|---|
statementAnalysisId | uuid | ID of the statement analysis |
proposalId | uuid | ID of the created proposal |
analysis.rejected
A statement analysis was completed.
Attribute | Type | Description |
---|---|---|
statementAnalysisId | uuid | ID of the statement analysis |
Get All Events
curl "https://example.com/api/events" \
-H "Authorization: 01234567890abcdef"
The above command returns JSON structured like this:
{
"object": "list",
"hasMore": false,
"data": [
{
"id": "680adba7-d2a8-4df7-82b4-01ae0411827f",
"object": "event",
"time": 1650297407,
"type": "statement_analysis.requested",
"data": {
"statementAnalysisId": "477966ab-69b7-4253-a1c6-dd8700de6bd5",
"agentId": 12345,
"name": "Acme March 2022"
}
},
{
"id": "1ac3b8ad-726d-4a0c-9821-88dd409e8487",
"object": "event",
"time": 1650297962,
"type": "statement_analysis.completed",
"data": {
"statementAnalysisId": "477966ab-69b7-4253-a1c6-dd8700de6bd5",
"proposalId": "059036f7-2f35-43c5-b968-46dc082ecf33"
}
},
{
"id": "46cf64a1-a493-4236-a108-5a18884d10aa",
"object": "event",
"time": 1650299106,
"type": "statement_analysis.requested",
"data": {
"statementAnalysisId": "8a4e5959-0ff5-4b67-9441-e131ba6f1514",
"agentId": 23456,
"name": "Mar 22 Merchant Statement.pdf"
}
},
{
"id": "9bbaff5b-0177-4521-a3f1-96db1e28eab5",
"object": "event",
"time": 1650301580,
"type": "statement_analysis.completed",
"data": {
"statementAnalysisId": "8a4e5959-0ff5-4b67-9441-e131ba6f1514",
"proposalId": "326a4ced-9790-4e28-8a67-fc8f986f0948"
}
},
]
}
This endpoint retrieves all events. If hasMore
is true
then more events are available which can be fetched using the startAfterId
query parameter.
HTTP Request
GET https://example.com/api/events
Query Parameters
Parameter | Default | Description |
---|---|---|
limit | 25 | Limit the number of events returned (valid values are integers 1 to 100). |
startTime | None | Only include events created at this time or later (must be integer number of seconds since Unix epoch). |
startAfterId | None | Only include events after event with this ID (must be UUID). Can be used for pagination. |
Get a Specific Event
curl https://example.com/api/events/602a7d68-f732-447f-86d6-65005152dde1 \
-H 'Authorization: 01234567890abcdef'
The above command returns JSON structured like this:
{
"id": "602a7d68-f732-447f-86d6-65005152dde1",
"object": "event",
"time": 1650301630,
"type": "statement_analysis.completed",
"data": {
"statementAnalysisId": "477966ab-69b7-4253-a1c6-dd8a00de6bd5",
"proposalId": "f841cda7-d34f-48c3-b803-412ca4179736"
}
}
This endpoint retrieves a specific event.
HTTP Request
GET https://example.com/api/events/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the event to retrieve |
Webhooks
Webhooks are a way of being notified when an event occurs.
Get All Webhooks
curl "https://example.com/api/webhooks" \
-H "Authorization: 01234567890abcdef"
The above command returns JSON structured like this:
{
"object": "list",
"data": [
{
"id": 1234,
"object": "webhook",
"url": "https://example.com/requested",
"eventTypes": [
"statement_analysis.requested"
],
"hmacSecret": "11f2baa04e4642de3b5c3d66ada815bc2d8a8515e00b08285d159a8d72993bfc"
},
{
"id": 56789,
"object": "webhook",
"url": "https://example.com/finished",
"eventTypes": [
"statement_analysis.completed",
"statement_analysis.rejected"
],
"hmacSecret": "a91e971e50388871a355b55423a909786381f2628353fba939c4ba19302d3734"
}
]
}
This endpoint retrieves all webhooks.
HTTP Request
GET https://example.com/api/webhooks
Get a Specific Webhook
curl "https://example.com/api/webhooks/1234" \
-H "Authorization: 01234567890abcdef"
The above command returns JSON structured like this:
{
"id": 1234,
"object": "webhook",
"url": "https://example.com/requested",
"eventTypes": [
"statement_analysis.requested"
],
"hmacSecret": "11f2baa04e4642de3b5c3d66ada815bc2d8a8515e00b08285d159a8d72993bfc"
}
This endpoint retrieves a specific webhook.
HTTP Request
GET https://example.com/api/webhooks/{id}
URL Parameters
Parameter | Description |
---|---|
id | The ID of the webhook to retrieve |
Create a Webhook
curl https://example.com/api/webhooks \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X POST \
-d '{"url": "https://example.com/webhook", "eventTypes": ["statement_analysis.completed", "statement_analysis.rejected"]}'
The above command returns JSON structured like this:
{
"id": 1234,
"hmacSecret": "4eb417493e09ac36ee2d998b6fb4306f1d428ae4577f30d521cd703f598f117b"
}
This endpoint creates a webhook.
HTTP Request
POST https://example.com/api/webhooks
Required Attributes
Attribute | Type | Description |
---|---|---|
url | string | URL to send webhook requests |
eventTypes | array | Only events of these types that will be delivered |
Update a Webhook
curl https://example.com/api/webhooks/1234 \
-H 'Authorization: 01234567890abcdef' \
-H 'Content-Type: application/json' \
-X PATCH \
-d '{"url": "https://example.com/webhook", "eventTypes": ["statement_analysis.completed", "statement_analysis.rejected"]}'
The above command returns an HTTP 200 without a body.
This endpoint updates a webhook.
HTTP Request
PATCH https://example.com/api/webhooks/{id}
Required Attributes
Attribute | Type | Description |
---|---|---|
id | integer | ID of webhook to update |
url | string | URL to send webhook requests |
eventTypes | array | Only events of these types that will be delivered |
Delete a Webhook
curl https://example.com/api/webhooks/1234 \
-H 'Authorization: 01234567890abcdef' \
-X DELETE
The above command returns an HTTP 200 without a body.
This endpoint deletes a webhook.
HTTP Request
DELETE https://example.com/api/webhooks/{id}
Required Attributes
Attribute | Type | Description |
---|---|---|
id | integer | ID of webhook to update |
Request Signatures
Webhook requests include a Isoamp-Signature
header that is the signature of the request. The signature consists of multiple key=value
pairs separated by commas. The value of the pair with the key t
is the time the request was sent in Unix time. The value of the pair with the key v1
is an HMAC of t
and the request body keyed by the webhook hmacSecret
.
To validate a signature concatenate t
with the request body. Compute an HMAC of this with key hmacSecret
and the SHA-256 algorithm. For example this could be done with the following code in Ruby.
require 'openssl' # => true
# isoamp_signature is the value of the "Isoamp-Signature" header.
isoamp_signature = "t=1650654842,v1=143f3835f2bf090fa6fd78754517d51b1897f691682627d241c5ed309cad0515"
# body is complete request body.
body = '{"id":"f9a6e449-e884-4726-973e-26d6bd99666a","object":"event","time":1650654842,"type":"statement_analysis.completed","data":{"statementAnalysisId":"f472949d-8227-4514-aa1c-b40f1f00380c","proposalId":"f9a4bb9c-d
2b2-45fa-83fe-f895c74235ad"}}'
# hmac_secret is a unique attribute for each webhook.
hmac_secret = "f76fab345ce93a69aa77d68a08283400cd0b45cb0a0a16b61e20b4c1e626a115"
# Parse the signature.
sig_parts = isoamp_signature.split(",").map { |pair| pair.split("=") }.to_h
# => {"t"=>"1650654842", "v1"=>"143f3835f2bf090fa6fd78754517d51b1897f691682627d241c5ed309cad0515"}
expected_sig = OpenSSL::HMAC.hexdigest("SHA256", hmac_secret, "#{sig_parts["t"]}#{body}")
# => "143f3835f2bf090fa6fd78754517d51b1897f691682627d241c5ed309cad0515"
# Test v1 that matches the expected signature. (Use a constant time comparison in production.)
expected_sig == sig_parts["v1"] #=> true
# Test that the request was sent recently to prevent replay.
Time.at(sig_parts["t"].to_i) #=> 2022-04-22 14:14:02 -0500
Login Via Link
Your application can generate links that automatically log a user in and redirect them to a specific page.
You will need to create a login link secret key. Go to the Admin -> Developer -> Single Sign on page and create a key.
require "openssl"
require "json"
# The secret key from your Login Link Secret Key in the Admin -> SSO page.
secret_key = "wNAUjLMjoj3DwfHArAsCgNuJGhaEdmFE"
message = {
"email" => "user@example.com",
"name" => "Joe User",
"destination" => "/courses"
}
# The message must be first JSON encoded and then hex encoded.
encoded_message = JSON.generate(message).unpack("H*").first
# => "7b22656d61696c223a2275736572406578616d706c652e636f6d222c226e616d65223a224a6f652055736572222c2264657374696e6174696f6e223a222f636f7572736573227d"
unix_time = Time.now.to_i # => 1662584892
version = 1
signature = OpenSSL::HMAC.hexdigest("SHA256", secret_key, "#{encoded_message}#{unix_time}#{version}")
# => "3c795e4f01178c7b261397e995b7ffedeceaad1bb9e85381466a65dbde4b387b"
url = "https://example.com/login_via_link?m=#{encoded_message}&t=#{unix_time}&v=#{version}&s=#{signature}"
# => "https://example.com/login_via_link?m=7b22656d61696c223a2275736572406578616d706c652e636f6d222c226e616d65223a224a6f652055736572222c2264657374696e6174696f6e223a222f636f7572736573227d&t=1662584892&v=1&s=3c795e4f01178c7b261397e995b7ffedeceaad1bb9e85381466a65dbde4b387b"
First, generate an authentication message with the following keys.
Attribute | Type | Description |
---|---|---|
string | Email address of user to log in | |
name | string | Name of user to log in |
destination | string | Site-relative path to redirect to after login |
Encode this message as JSON and then hex encode the JSON.
Concatenate the hex encoded JSON object, the Unix time, and "1" together. The "1" is the version indicator for the type of secure login link. This is the message blob that will be signed in the next step.
Perform a SHA-256 HMAC of this message blob using the secret key.
The login via link URL is: https://example.com/login_via_link
.
Add the following query parameters:
Parameter | Description |
---|---|
m | Hex encoded JSON authentication message |
s | HMAC signature |
t | Unix time |
v | Version (always 1) |
This should yield a URL like the following:
https://example.com/login_via_link?m=7b22656d61696c223a2275736572406578616d706c652e636f6d222c226e616d65223a224a6f652055736572222c2264657374696e6174696f6e223a222f636f7572736573227d&t=1662584892&v=1&s=3c795e4f01178c7b261397e995b7ffedeceaad1bb9e85381466a65dbde4b387b
The login link secret key page also includes a live example of building a login URL.
Embedding
<iframe
width="800"
height="600"
allow="fullscreen"
src="https://example.com/login_via_link?m=7b2264657374696e6174696f6e223a222f636f75727365733f656d6265643d74727565222c22656d61696c223a22737570706f72742b3065653966653961313934646661383040636373616c657370726f2e636f6d222c226e616d65223a22537570706f7274227d&s=8919ec6e356551494d8e0e38833275bd65d4b0a56992f19cbab13eeff6e0d974&t=1662569468&v=1"
>
</iframe>
The ISO Amp training system can be embedded in your application via iframe
.
This is particularly useful when combined with Login Via Link. Generate a URL and use it as the src
of your iframe
.
The link to the training portal is https://example.com/courses?embed=true
.
If you want to allow the videos to be played full screen you must set the allow
attribute appropriately.