Postman Collection
Testing vs Production
After creating an account you can access the test API endpoints on our sandbox server:
This endpoint is identical to our production endpoint but does not allow PHI and only returns dummy card results.
Once you have signed our Business Associate Agreement (BAA) you will be able to access the production server:
Admin Endpoints
The admin endpoints are designed for managing access tokens within our system. These endpoints can only be called using a valid API key. They provide a secure way to generate and manage tokens, ensuring that only authorized users can access sensitive data and functionalities.
Get Access Token
GET
https://sandbox.cardscan.ai/v1/access-token
This endpoint generates the JSON Web Token (JWT) for a web or mobile user
Query Parameters
Name Type Description Unique identifier for the user
200 401 403
Copy {
"IdentityId" : "us-east-1:0236cb77-ac53-460d-ba39-60b186af2897" ,
"Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}
Copy {
"message" : "Unknown authorization error - please check your token format and try again" ,
"type" : "Unauthorized" ,
"code" : 401
}
Copy {
"message" : "API Key is not registered" ,
"type" : "Unauthorized" ,
"code" : 401
}
This endpoint generates a short-lived session token that the web/mobile user will use to directly authenticate with CardScan's servers. See the Authentication page for more details.
This function takes an optional user_id
which must be unique between your users.
See Authentication for code examples.
Insurance Card Scanning Endpoints
Create Card
POST
https://sandbox.cardscan.ai/v1/cards
Creates a card object to initiate the scanning process and will be used for generating upload endpoints.
Request Body
Name Type Description Enabled scanning of both sides of the insurance cards. Important for eligibility checks and prior auth.
Default : False
Allows the card to process multiple updates per side. Required for live scanning.
Default : False
201: Created Successful Operation 400: Bad Request Bad Request
Copy {
"card_id" : "171d11c4-9154-4f2f-b4ca-0fb610abe05e" ,
"state" : "pending" ,
"created_at" : "2024-02-05 15:50:14.856792"
}
Copy {
"message" : "enable_backside_scan must be a boolean" ,
"type" : "Bad Request" ,
"code" : 400
}
Curl
Copy curl --location 'https://sandbox.cardscan.ai/v1/cards' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer endusertokenXXX' \
--data '{
"enable_backside_scan": true
}'
Generate Upload Url
POST
https://sandbox.cardscan.ai/v1/cards/:card_id/generate-upload-url
Generates a URL and signed payload to enable direct image upload to AWS S3.
Path Parameters
Name Type Description For the card entity to link the upload with.
Request Body
Name Type Description 'front ' - the front face of the insurance card, often containing the name, member_id, etc.
'back ' - the back side of the card, often containing the claims address, and various phone number.
200 Successful Operation 400 Invalid parameters 401 Missing token or other error 403 Bad or expired token
Copy {
"card_id" : "4c901279-622f-485f-85cc-aad1f12c2d8e" ,
"upload_url" : "https://cardscan-sandbox.s3.amazonaws.com/" ,
"upload_parameters" : {
"key" : "4c901279-622f-485f-85cc-aad1f12c2d8e" ,
"x-amz-algorithm" : "AWS4-HMAC-SHA256" ,
"x-amz-security-token": "BADCAFEb3JpZ2sddsfdsfrIAiACLcnulBVymY22qkf3M8XDvlhXweRzDe8V95X73BextSqDAgiU//////////8BEAAaDDUzNTc5NTY3OTQ2NiIM1ZoFizA0PWXBXfiWKtcBVOcw4ss3VbqdPFO7OTJmxuPLUnPKNbsMaRF5sNEsqecP74+mucNgjAwigvQM3K0Bb/WqTsmGIkGXT7p+St1XpyB9nY+nVE1cVgtkggwU4UDXhBpnZLhQIE5fLjEBU+X0Gwd7WVXJdwXFa5iD+EwsQU2aJihBc1tdxYXmIZIkMQ1UXdFPbRc1vX4wcDgzrfbvT5749d1rOh5u9mKxTNc7z/1G4aYswrODlh5N/hSamcKGlaC/wwxrv8gwY64QEp/nQkUuTdrKPSrQRUb7Z5Fj7m8erRixTtYI2rOfAl5Cl",
"x-amz-credential" : "FAKEKEYSDONOTUSEXZYABC/20210413/us-east-1/s3/aws4_request" ,
"x-amz-date" : "20210413T210019Z" ,
"policy": "eyJleHBpcmF0aW9uIjogIjIwMjEtMDQtMTNUMjI6MDA6MTlaIiwgImNvbmRpdGlvbnMiOiBbeyJidWNrZXQiOiAiY2FyZHNjYW4tc2FuZGJveCJ9LCB7ImtleSI6ICI0YzkwMTI3OS02MjJmLTQ4NWYtODVjYy1hYWQxZjEyYzJkOGUifSwgeyJ4LWFtei1hbGdvcml0aG0iOiAiQVdTNC1ITUFDLVNIQTI1NiJ9LCB7IngtYW16LWNyZWRlbnRpYWwiOiAiQUtJSEFMUk9CSVZGTkZYWllBQkMvMjAyMTA0MTMvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJ9LCB7IngtYW16LWRhdGUiOiAiMjAyMTA0MTNUMjEwMDE5WiJ9XX0=",
"x-amz-signature" : "40da5a6814f646d9ded38539e37d6badcafe808494b04c76d37ccc89a3e5d34d"
}
}
Copy {
"message" : "expiration must be between 100 and 3600" ,
"type" : "Bad Request" ,
"code" : 400
}
Copy {
"message" : "Unknown authorization error - please check your token format and try again" ,
"type" : "Unauthorized" ,
"code" : 401
}
Copy {
"message" : "Token is expired" ,
"type" : "Authentication Timeout" ,
"code" : 419
}
The S3 URL only supports HTTP POSTs , not PUTs.
The upload_parameters
may change at any time, please make sure to not hardcode the list in any POST command.
Curl Javascript Swift
Copy curl --location 'https://sandbox.cardscan.ai/v1/cards/9d709b16-3807-4fc9-b176-4409241beab5/generate-upload-url' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer endusertokenXXX \
--data ' {
"orientation" : "back"
}'
Copy // The JS client wraps generate-upload-url in with the file upload functionality.
const client = new CardScanApi ({
sessionToken : token ,
live : false
});
client .uploadCardImage (file)
.then ((cardId) => {
//update UI.
})
.catch ((error) => {
//retry or update UI
});
Copy // The swift client wraps generate-upload-url with the file upload functionality.
let apiClient = CardScanAPIClient ( userToken : userToken, live : false )
apiClient. uploadCardImage ( image : image ) { result in
switch result {
case . failure ( let error ) :
//check error, retry, update UI.
print ( "uploadCardImage error \(error) " )
case . success ( let cardId ) :
//update UI for success!
}
}
List Scanned Cards
GET
https://sandbox.cardscan.ai/v1/cards
Query Parameters
Name Type Description Used to paginate through results when count is greater that limit.
Count of cards to return.
Default : 50
Max: 500
200 Successful Response 400 Invalid parameters 401 Missing or invalid token 403 Token is expired
Copy {
"cards" : [
{
"card_id" : "1bab2f3c-cfbe-4f22-b480-b389ece57f7e" ,
"state" : "pending" ,
"created_at" : "2021-07-30 19:56:40.638894+00:00" ,
} ,
{
"card_id" : "98405a1e-b367-4b3a-876a-e7886b7e1b69" ,
"state" : "processing" ,
"created_at" : "2021-07-30 20:26:40.838094+00:00" ,
} ,
{
"card_id" : "4c901279-622f-485f-85cc-aad1f12c2d8e" ,
"state" : "error" ,
"created_at" : "2021-07-30 20:58:50.334343+00:00" ,
"error_message" : "Failure during OCR process - [E507]"
} ,
{
"card_id" : "a1d743ee-3bb9-468d-a2c5-4e33fa0e1c6e" ,
"state" : "completed" ,
"created_at" : "2021-07-31 18:36:33.567313+00:00" ,
"details" : {
"group_number" : {
"value" : "98755" ,
"scores" : [
"0.9994" ,
"0.9828"
]
} ,
"member_number" : {
"value" : "128845682" ,
"scores" : [
"0.9984" ,
"0.9618"
]
} ,
"member_name" : {
"value" : "emily dickinson" ,
"scores" : [
"0.9974" ,
"0.8879"
]
} ,
"plan_name" : {
"value" : "unitedhealthcare choice plus" ,
"scores" : [
"0.9953" ,
"0.9835"
]
} ,
"plan_id" : {
"value" : "(80840) 911-80708-01" ,
"scores" : [
"0.9942" ,
"0.9939"
]
}
}
}
] ,
"response_metadata" : {
"limit" : 4 ,
"next_cursor" : "IieuzkckWq0"
}
}
Copy {
"message" : "limit must be a positve integer and less than 500" ,
"type" : "Bad Request" ,
"code" : 400
}
Copy {
"message" : "Unknown authorization error - please check your token format and try again" ,
"type" : "Unauthorized" ,
"code" : 401
}
Copy {
"message" : "Token is expired" ,
"type" : "Authentication Timeout" ,
"code" : 419
}
The next_cursor
field is only present in the response_metadata
when there are additional results to request.
The completed
card in this example is truncated, for a full card and supported states, please see Get Card Details below.
Curl Javascript Swift
Copy curl --location --request GET 'https://sandbox.cardscan.ai/v1/cards' \
--header 'Authorization: Bearer endusertokenXXX'
Copy const client = new CardScanApi ({
sessionToken : token ,
live : false
});
client .listCards ()
.then ((cards) => {
//update UI.
})
.catch ((error) => {
//retry or update UI
});
Copy let apiClient = CardScanAPIClient ( userToken : userToken, live : false )
apiClient. listCards ( limit : 10 ) { result in
switch result {
case . failure ( let error ) :
print ( "listCards error \(error) " )
case . success ( let cards ) :
//update UI
}
}
Get Card
GET
https://sandbox.cardscan.ai/v1/cards/:cardId
Path Parameters
200 Successful response 400 Invalid UUID 401 Missing or invalid token 403 Token is expired 404 Card not found
Copy {
"card_id" : "a1d743ee-3bb9-468d-a2c5-4e33fa0e1c6e" ,
"state" : "completed" ,
"created_at" : "2021-07-31 18:36:33.567313+00:00" ,
"details" : {
"group_number" : {
"value" : "98755" ,
"scores" : [
"0.9994" ,
"0.9828"
]
} ,
"member_number" : {
"value" : "128845682" ,
"scores" : [
"0.9984" ,
"0.9618"
]
} ,
"rx_bin" : {
"value" : "610279" ,
"scores" : [
"0.9979" ,
"0.9842"
]
} ,
"rx_pcn" : {
"value" : "9987" ,
"scores" : [
"0.9991" ,
"0.9147"
]
} ,
"member_name" : {
"value" : "emily dickinson" ,
"scores" : [
"0.9974" ,
"0.8879"
]
} ,
"plan_name" : {
"value" : "unitedhealthcare choice plus" ,
"scores" : [
"0.9953" ,
"0.9835"
]
} ,
"plan_id" : {
"value" : "(80840) 911-80708-01" ,
"scores" : [
"0.9942" ,
"0.9939"
]
} ,
"card_specific_id" : {
"value" : "87726" ,
"scores" : [
"0.997" ,
"0.9592"
]
}
}
}
Copy {
"message" : "Invalid card_id, the ID must be formatted as a UUID." ,
"type" : "Bad Request" ,
"code" : 400
}
Copy {
"message" : "Unknown authorization error - please check your token format and try again" ,
"type" : "Unauthorized" ,
"code" : 401
}
Copy {
"message" : "Token is expired" ,
"type" : "Authentication Timeout" ,
"code" : 419
}
Copy {
"message" : "No resource found for card_id - a1d743ee-3bb9-468d-a2c5-4e33fa0e1c6a" ,
"type" : "Not Found" ,
"code" : 404
}
Cards returned by this endpoint and the /v1/cards
endpoint have a state field:
Value Description This card ID has been reserved but a corresponding file has not yet been uploaded
The card is being processed by our ML pipeline.
Card processing is completed and the card details
are available.
An error has occurred, see error_message
for more details.
An unknown issue has occurred, please contact support for help.
After being processed by the ML pipeline, each element is labeled and when the probability is above our minimum threshold the results are returned.
Name Description Example The group number identifies the specific benefits associated with the plan. This is missing with some payers and exchange plans.
A unique identifier for each member and dependent. This is used to verify coverage and arrange payment for services.
The name of the health insurance payer or 3rd party administrator.
The payer ID or EDI for the insurance company. This is as written on the card and not matched to a clearing house.
rx_bin
rx_pcn
rx_group
rx_id
These are used to identify how a prescription drug will be reimbursed and where a pharmacy can send a reimbursement claim to
Most often the policyholder, but on some cards this is the dependent the card was issues to.
This is a list of all dependents found on the card.
Our best attempt to determine the name of the plan for this card. This is missing on many cards.
unitedhealthcare choice plus
An identifier representing the plan associated with this card.
The name of the employer who is contracted with the 3rd party administrator.
When available a list of: deductibles, co-pays, co-insurance, PCP name.
The date when coverage starts.
A non-specific but prominent identifier found on the card.
A list of all phone numbers found of the front and back of the card.
A list of all addresses found on the card.
UnitedHealthcare
P.O. Box 740800
Atlanta, GA 30374-0800
Note: If an element is missing it means it is either not available on this type of card, or we did not have a high enough confidence to return it.
Curl Javascript Swift
Copy curl --request GET 'https://sandbox.cardscan.ai/v1/cards/a1d743ee-3bb9-468d-a2c5-4e33fa0e1c6e' \
--header 'Authorization: Bearer endusertokenXXX'
Copy const client = new CardScanApi ({
sessionToken : token ,
live : false
});
client .getCard (cardId)
.then ((card) => {
//update UI.
})
.catch ((error) => {
//retry or update UI
});
Copy let apiClient = CardScanAPIClient ( userToken : userToken, live : false )
apiClient. getCard ( cardUUID : cardId ) { result in
switch result {
case . failure ( let error ) :
print ( "getCard error \(error) " )
case . success ( let card ) :
//update UI
}
}
Delete Card
DELETE
https://sandbox.cardscan.ai/v1/cards/:cardId
This will trigger a soft delete of the specified card.
Path Parameters
Note : All of the images, ML results, eligibility results, and PHI will be removed, but the card record and performance statistics will remain.
Curl
Copy curl --request DELETE 'https://sandbox.cardscan.ai/v1/cards/a1d743ee-3bb9-468d-a2c5-4e33fa0e1c6e' \
--header 'Authorization: Bearer endusertokenXXX'
Flag Card
POST
https://sandbox.cardscan.ai/v1/cards/:cardId/flag
This endpoint allows you to flag a specific card with a particular type of flag. Flags are used to mark cards for special attention or action.
Path Parameters
Request Body
Name Type Allowed values Description The flag type used to mark the card
An optional message to add additional information
200 Successful response 400 Flag type required 400 Invalid flag type
Copy {
"message" : "Card flagged successfully"
}
Copy {
"message" : "flag_type is required" ,
"type" : "Bad Request" ,
"code" : 400
}
Copy {
"message" : "Invalid flag_type" ,
"type" : "Bad Request" ,
"code" : 400
}
Magic Links
Generate magic link
GET
/generate-magic-link
Generates a magic link for the currently authenticated user. The generated token expires in one hour. This endpoint is called by the React Widget when using the Web To Mobile Handoff feature.
200 403
Copy {
"magic_link" : "https://sandbox.cardscan.ai/v1/validate-magic-link?token=<token>" ,
"token" : "<token>" ,
"expires_at" : "2024-06-27T03:48:01.049866"
}
Copy {
"message" : "User is not authorized for this resource" ,
"type" : "Access Denied" ,
"code" : 403
}
Curl Javascript
Copy curl --request GET 'https://sandbox.cardscan.ai/v1/generate-magic-link \
--header ' Authorization: Bearer endusertokenXXX '
Copy const client = new CardScanApi ({
sessionToken : token ,
live : false
});
client .generateMagicLink ()
.then ((response) => {
// ...
})
.catch ((error) => {
// ...
});
Validate magic link
GET
/validate-magic-link?token=<magic-token>
Validates that the provided magic link token is valid and if so, returns an Access Token with limited capabilities. You need to use this endpoint if you want to self-host the Web To Mobile Handoff feature.
200 400: Invalid token 410: Expired token 404
Copy {
"IdentityId" : "us-east-1:0236cb77-ac53-460d-ba39-60b186af2897" ,
"Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}
Copy {
"message" : "Invalid token" ,
"type" : "Bad Request" ,
"code" : 400
}
Copy {
"message" : "Token expired - <token>" ,
"type" : "Expired" ,
"code" : 410
}
Copy {
"message" : "No resource found for token - badtokenbadtok" ,
"type" : "Not Found" ,
"code" : 404
}
Curl Javascript
Copy curl --request GET 'https://sandbox.cardscan.ai/v1/validate-magic-link?token=<token> \
--header ' Authorization: Bearer endusertokenXXX '
Copy const token = "your-magic-token" ;
fetch ( ` ${ baseURL } /validate-magic-link?token= ${ token } ` )
.then ((res) => res .json ())
.then ((data) => {
setToken ( data .Token); // Access token
})
.catch ((err) => console .log (err));
Eligibility Verification
Our Eligibility Verification Endpoints offer a seamless way to check the insurance eligibility of patients. They provide real-time verification of coverage details, ensuring accurate and efficient processing of healthcare services.
Please see the Eligibility Verification page for full details on the product offering.
Our Eligibility Verification Endpoints operate similarly to our Insurance Card Scanning Endpoints. Users can create a new eligibility request, which is processed asynchronously. The system updates the record as the state changes, providing real-time insights into insurance coverage and benefits.
Note: Currently a completed insurance card scan is required to start the eligibility verification process.
To create an eligibility request, users must provide subscriber and dependent demographics along with provider details, including a National Provider Identifier (NPI). This information is essential for accurately verifying insurance eligibility.
You can locate a providers NPI on the NPPES NPI Registry search page.
Last updated 3 months ago