Skip to main content

Claim Submission Workflow

The Claim Submission API enables applications to submit consumer FSA/HSA claims to TPAs programmatically. Silver handles the communication to the TPA, whether that's through email, fax, mail, or SFTP upload, depending on what the TPA supports.

Environments

EnvironmentBase URL
Staginghttps://claim-submission-staging.withsilver.app
Productionhttps://claim-submission.withsilver.app

Use the staging environment during development and testing. Claims sent in Staging do not get sent to providers. You will receive a staging API key from Silver during onboarding.

Test Provider

A test provider can be created for you in the staging environment so you can exercise the full submission flow and receive the claims to an email address of your chosing. Contact Silver to get it set up for your account.

Submission Flow

Step 1: List Providers

Retrieve the providers available for your partner account. Each provider represents a TPA that Silver can submit claims to.

curl -X GET https://claim-submission.withsilver.app/v1/providers \
-H "apiKey: your-partner-api-key"

Response:

[
{
"id": "901392c2-1d41-40f8-abcb-1995e4a7e297",
"name": "Navia",
"logo": "https://ocvtbxkudfyeyziuewun.supabase.co/storage/v1/object/public/assets/providers/901392c2-1d41-40f8-abcb-1995e4a7e297/navia-logo.png",
"type": "FSA"
},
{
"id": "a3be11fe-ba46-4a39-bac7-d3530719c276",
"name": "Navia",
"logo": "https://ocvtbxkudfyeyziuewun.supabase.co/storage/v1/object/public/assets/providers/a3be11fe-ba46-4a39-bac7-d3530719c276/navia-logo.png",
"type": "HSA"
}
]

Each provider has:

  • id — UUID used in subsequent API calls
  • name — Display name of the TPA
  • logo — URL to the provider's logo image
  • type — Account type: FSA, HSA, etc. Note that the same TPA may appear multiple times with different types
Provider list is dynamic

Providers and their forms may change over time as Silver adds new TPAs or TPAs update their claim processes. Always fetch the provider list dynamically rather than caching it long-term.

Step 2: Get Provider Form Requirements

Fetch the provider's details including the form fields that must be collected from the user and included in the claim submission.

curl -X GET https://claim-submission.withsilver.app/v1/providers/901392c2-1d41-40f8-abcb-1995e4a7e297 \
-H "apiKey: your-partner-api-key"

Response:

{
"id": "901392c2-1d41-40f8-abcb-1995e4a7e297",
"name": "Navia",
"logo": "https://ocvtbxkudfyeyziuewun.supabase.co/storage/v1/object/public/assets/providers/901392c2-1d41-40f8-abcb-1995e4a7e297/navia-logo.png",
"type": "FSA",
"form_requirements": [
{
"label": "First Name",
"id": "first_name",
"type": "string",
"validator": "raw",
"required": true,
"auto_fill_hints": ["given_name"]
},
{
"label": "Last Name",
"id": "last_name",
"type": "string",
"validator": "raw",
"required": true,
"auto_fill_hints": ["family_name"]
},
{
"label": "SSN or Employee ID",
"compliance_label": "Employee ID",
"id": "ssn_or_id",
"type": "string",
"validator": "number",
"required": true
},
{
"label": "Telephone Number",
"id": "telephone_number",
"type": "string",
"validator": "phone",
"required": true,
"auto_fill_hints": ["telephone_number_national"]
},
{
"label": "Email Address",
"id": "email_address",
"type": "string",
"validator": "email",
"required": true,
"auto_fill_hints": ["email"]
}
]
}

(Truncated for brevity — the actual Navia response includes 10 fields.)

Use the form_requirements array to build your claim submission form dynamically. Each field object includes:

  • id — The key to use in user_form_fields when submitting the claim
  • label — Display text for the form field
  • type — Input type (see Form Requirements Reference)
  • validator — Validation rule to apply (see Form Requirements Reference)
  • required — Whether the field must be included
  • auto_fill_hints — Suggestions for browser/device autofill
  • compliance_label — Optional alternate label some partners may prefer to display instead of label. Please let Silver know if you have compliance requirements that do not allow you to capture Social Security Numbers.
Always fetch dynamically

Always fetch the provider's form_requirements dynamically rather than hardcoding fields. Requirements can change when a TPA updates their claim form.

Include all fields in your submission

When building user_form_fields, include every field from form_requirements — even those marked required: false. For optional fields the user doesn't fill in, submit an empty string (""). Omitting a field entirely can cause the submission to fail.

For a complete reference of all field types (string, radio, radiotext, date), validators, input formatters, and their properties, see the Form Requirements Reference.

Step 3: Upload Claimable Documents

Upload the claim documentation along with line-item services. Each upload returns a document ID to reference when submitting the claim.

There are two types of documents in a submission:

  • file — The primary document: the receipt or invoice for the service. Must be base64-encoded.
  • supporting_documents — Optional additional evidence such as a Letter of Medical Necessity (LMN). Also base64-encoded.
curl -X POST https://claim-submission.withsilver.app/v1/claimable_documents \
-H "apiKey: your-partner-api-key" \
-H "Content-Type: application/json" \
-d '{
"user_id": "your-user-id",
"document_type": "receipt",
"file": {
"base64": "JVBERi0xLjQKJcfs...",
"mime_type": "application/pdf"
},
"claimable_services": [
{
"service_date_start": "2026-01-10",
"service_date_end": "2026-01-10",
"service_provider": "Downtown Physical Therapy",
"service_description": "Physical therapy session — 60 min",
"claimable_amount": 150.00
}
],
"supporting_documents": [
{
"base64": "iVBORw0KGgoAAAANS...",
"mime_type": "image/png"
}
]
}'

Response: Returns the claimable document ID as a string (UUID).

Request fields:

FieldRequiredDescription
user_idYesYour identifier for the user
document_typeYesType of document (e.g. receipt)
fileYesBase64-encoded primary document (receipt/invoice) with base64 and mime_type
claimable_servicesNoArray of line-item services on this document
supporting_documentsNoArray of base64-encoded supporting documents (e.g. LMN)

Claimable service fields:

FieldRequiredDescription
service_date_startYesService start date (YYYY-MM-DD)
service_date_endYesService end date (YYYY-MM-DD)
service_providerYesName of the service provider
service_descriptionYesDescription of the service
claimable_amountYesAmount in dollars (e.g. 150.00)
skuNoProduct identifier
sku_typeNoType of SKU (e.g. UPC)

You can also manage services on a document after creation:

  • List services: GET /v1/claimable_documents/{id}/claimable_services
  • Remove a service: DELETE /v1/claimable_documents/{document_id}/claimable_services/{service_id}

Step 4: Submit the Claim

Submit the claim referencing the uploaded documents, the chosen provider, the required form fields, and the member's signature.

curl -X POST https://claim-submission.withsilver.app/v1/claims \
-H "apiKey: your-partner-api-key" \
-H "Content-Type: application/json" \
-d '{
"user_id": "your-user-id",
"provider_id": "901392c2-1d41-40f8-abcb-1995e4a7e297",
"plan_period_start": "2026-01-01",
"plan_period_end": "2026-12-31",
"user_form_fields": {
"first_name": "Jane",
"last_name": "Smith",
"ssn_or_id": "123456",
"telephone_number": "5551234567",
"email_address": "jane@example.com",
"employer_name": "Acme Corp",
"street": "123 Main St",
"city": "Seattle",
"state": "WA",
"zip_code": "98101"
},
"signature": "iVBORw0KGgoAAAANSUhEUgAA...",
"claimable_documents": ["e4b0a99b-1887-46b1-b026-0907f8e59474"]
}'

Response:

{
"claim_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"user_provider_id": "f9e8d7c6-b5a4-3210-fedc-ba9876543210"
}

Request fields:

FieldRequiredDescription
user_idYesYour identifier for the user
provider_idYesProvider UUID from Step 1
plan_period_startNoPlan year start date (YYYY-MM-DD)
plan_period_endNoPlan year end date (YYYY-MM-DD)
user_form_fieldsYesObject with keys matching id values from the provider's form_requirements
signatureYesBase64-encoded PNG of the member's signature
claimable_documentsYesArray of document IDs from Step 3 (must include at least one with claimable services)

Idempotency

The POST /v1/claimable_documents and POST /v1/claims endpoints support idempotency. Include an Idempotency-Key header with a unique string to safely retry requests without creating duplicates.

curl -X POST https://claim-submission.withsilver.app/v1/claims \
-H "apiKey: your-partner-api-key" \
-H "Idempotency-Key: unique-request-id-12345" \
-H "Content-Type: application/json" \
-d '{ ... }'

Behavior:

  • If the key matches a completed request with the same body, the original response is returned.
  • If the key matches a request that is still processing, a 409 Conflict is returned.
  • If the key was used with a different request body, a 422 Unprocessable Entity is returned.
  • Keys expire after 24 hours.

Best Practices

  1. Fetch form requirements dynamically — Provider forms can change at any time. If you save form fields for a user, you might get a 4xx error if the fields have changed.
  2. Upload documents before submitting — All document uploads must complete before the claim is submitted.
  3. Store the claim ID — Save the returned claim_id for tracking and customer support purposes.
  4. Include all line-item services — When uploading documents, include the claimable_services array with accurate service dates, amounts, and descriptions.
  5. Use idempotency keys — Always include an Idempotency-Key header on POST requests to safely handle retries.
  6. Fetch the provider list Dynamically — Call GET /v1/providers when a user is present to show the latest providers avaialble. If you save this to a user's profile, you might get a 4xx error if the support has changed.