ICON Developer Center

Guides and reference

Standard responses

Every answer carries status, reason and code from one catalog. The tables below are generated from it.

Every JSON answer carries the same fields (the one exception: an unknown path answers a plain {"error": "Not found"}):

FieldWhat it is
statusThe outcome, always one of: accepted, saved, pending, held, rejected, invalid, failed.
reasonA short sentence-case explanation: Missing HS grad year, Not eligible - Program, Duplicate - Client.
codeA stable upper-case code. Branch on it; it never changes meaning.
retryableWhether the same request may succeed later without a change.
field / fieldsThe field(s) at fault, when there are any.
levelFor an eligibility refusal: where it applied (offer, program, bucket, campaign, affiliate, buyer).
sourceFor DUPLICATE: icon (ICON already has the lead) or buyer (the school's system said duplicate).

#Statuses

statusMeaning
acceptedThe request succeeded: a lead was sold, or a read answered.
savedThe lead was stored; nothing was sold.
pendingThe buyer has not decided yet.
heldA test lead, held by ICON before any buyer received it.
rejectedA valid request that ICON or the buyer declined (eligibility, cap, duplicate, …).
invalidThe request must change before it can succeed (a missing or bad field, consent, authentication).
failedNothing was decided (a timeout, a buyer or platform error); it may be retried.

#Reasons

A reason ends in - Client when the school's own system decided, and in - <Level> (- Offer, - Program, …) when ICON's rules at that level decided. A reason names a field when one is at fault: Invalid ZIP code. Reasons never carry the buyer's own words, internal rule names, limits or ids.

#Codes

The HTTP column lists every status a code can be served with. Decisions about a lead (accepted, refused, held) come with HTTP 200: read status and code.

#Success

codestatusDefault reasonRetryableHTTP
OKacceptedOKno200
ACCEPTEDacceptedLead acceptedno200
SAVEDsavedLead savedno200
PENDINGpendingPending - Clientno200, 202
TEST_LEAD_HELDheldTest lead heldno200

#Authentication and access

codestatusDefault reasonRetryableHTTP
AUTH_REQUIREDinvalidMissing API keyno401
AUTH_INVALIDinvalidInvalid API keyno401
FORBIDDENinvalidNot permittedno403
NOT_FOUNDinvalidNot foundno200, 400, 404

#Request

codestatusDefault reasonRetryableHTTP
METHOD_NOT_ALLOWEDinvalidMethod not allowedno405
MALFORMED_REQUESTinvalidMalformed requestno400, 409
REQUIRED_FIELD_MISSINGinvalidMissing required fieldno200, 400, 422
INVALID_FIELDinvalidInvalid fieldno200, 400, 422
BOT_CHECK_FAILEDinvalidBot check failedno400
RATE_LIMITEDfailedToo many requestsyes429

#Eligibility

codestatusDefault reasonRetryableHTTP
NOT_ELIGIBLErejectedNot eligibleno200
OFFER_UNAVAILABLErejectedOffer unavailableno200, 400, 404, 410

#Caps

codestatusDefault reasonRetryableHTTP
CAP_REACHEDrejectedCap reachedno200
CAP_UNAVAILABLEfailedCap check unavailableyes200, 503
codestatusDefault reasonRetryableHTTP
CONSENT_REQUIREDinvalidMissing TCPA consentno200, 400
CONSENT_INVALIDinvalidInvalid TCPA consentno400, 404, 409

#Duplicate

codestatusDefault reasonRetryableHTTP
DUPLICATErejectedDuplicate - Offerno200, 409

#Buyer decision

codestatusDefault reasonRetryableHTTP
BUYER_REJECTEDrejectedRejected - Clientno200, 502
BUYER_INVALID_FIELDinvalidInvalid field - Clientno200, 502
BUYER_NOT_ELIGIBLErejectedNot eligible - Clientno200, 502
BUYER_ERRORfailedError - Clientno200, 502

#Transport

codestatusDefault reasonRetryableHTTP
TIMEOUTfailedTimeout - Clientyes200, 504

#Platform

codestatusDefault reasonRetryableHTTP
UNAVAILABLEfailedTemporarily unavailableyes200, 503
INTERNAL_ERRORfailedInternal errorno500

#Buyer reasons

When a school's system refuses a lead, ICON translates its answer into one of these standardized reasons (a school that says it is full answers CAP_REACHED, Cap reached, like any other cap):

reasoncodefield
Rejected - ClientBUYER_REJECTED—
Duplicate - ClientDUPLICATE—
Location not served - ClientBUYER_NOT_ELIGIBLEzip
Age not eligible - ClientBUYER_NOT_ELIGIBLEdate_of_birth
Education not eligible - ClientBUYER_NOT_ELIGIBLEeducation_level
HS grad year not eligible - ClientBUYER_NOT_ELIGIBLEgrad_year
Program not offered - ClientBUYER_NOT_ELIGIBLEprogram_id
Invalid phone number - ClientBUYER_INVALID_FIELDphone
Invalid email - ClientBUYER_INVALID_FIELDemail
Invalid ZIP code - ClientBUYER_INVALID_FIELDzip
Invalid TrustedForm token - ClientBUYER_INVALID_FIELDtrustedform_cert_url
Consent not accepted - ClientBUYER_REJECTED—
Test lead - ClientBUYER_REJECTED—

The field column uses ICON's short field names (see the field dictionary). A buyer answer ICON cannot map reads Rejected - Client.

Generated 2026-09-28 from ICON's API definitions. Every page is also available as Markdown; the index is llms.txt.