Skip to navigation

Errors

Branch on code, show message, never parse prose.

Failures return a JSON object under an error key.

{
"error": {
"type": "invalid_request_error",
"code": "donor_not_found",
"message": "Donor 4MZ8RT2PW was not found.",
"param": "donor_id",
"doc_url": null,
"recovery": "Confirm the identifier is correct and belongs to this institution, then retry.",
"details": null
}
}
FieldUse it for
typeCoarse category, for deciding whether to retry at all.
codeBranch on this. Stable and machine-readable.
messageHuman-readable. Wording may change — never parse it.
paramThe field the error relates to, when it maps to one. A not-found or validation error caused by an ID that names no record always names the field that held it.
doc_urlLink to documentation for this error, when one exists.
recoveryPlain-language guidance you can surface to a person.
detailsPer-field failures on a validation error. Absent otherwise.

Types

typeMeaning
invalid_request_errorYour input: bad parameters, validation, not-found, conflict.
authentication_errorMissing or invalid credential.
rate_limit_errorThrottled. Back off and retry.
api_errorServer-side. Safe to retry.

Status codes

StatusWhen
400Malformed request, failed validation, or an unrecognised API key.
401Key missing or expired, or API access is not enabled for the institution.
403Key valid, but lacks the permission this endpoint needs, or the signed-in user’s own AwardSpring permissions do not cover this information. At sign-in, the email and password are correct but the account cannot use the app.
404No such record belongs to this institution, or the feature is not turned on for it.
409Conflicts with existing data, or an idempotent retry is still in flight.
422Well-formed but unprocessable — including unrecognised fields.
429Rate limited. See Rate limits.

Codes

Branch on these. They are stable; new ones may be added.

codeStatus
validation_failed400
invalid_cursor400
unsupported_activity_type400
unauthorized401
invalid_credentials401
invalid_refresh_token401
permission_required403
permission_denied403
app_access_denied403
donor_not_found404
student_not_found404
person_not_found404
scholarship_not_found404
award_cycle_not_found404
fund_not_found404
gift_not_found404
activity_not_found404
notification_not_found404
institution_not_found404
awarded_students_not_found404
donor_questions_unavailable404
app_endpoint_unavailable404
email_already_exists409
idempotency_key_in_flight409
idempotency_key_request_mismatch422
rate_limit_exceeded429
internal_error500

Validation failures

A validation_failed error carries details, one entry per offending field. Show these against the fields they name rather than concatenating them into one message.

{
"error": {
"type": "invalid_request_error",
"code": "validation_failed",
"message": "One or more validation rules failed. See details for specifics.",
"details": [
{ "field": "amount", "message": "Amount is required." },
{ "field": "gift_date", "message": "GiftDate is required." }
]
}
}

Accounts that cannot use the app

Signing in returns app_access_denied when the email and password are correct but belong only to a reviewer, student or donor account. Those accounts use the institution’s AwardSpring website, not the app. Tell the person so instead of asking them to retype their password, and do not retry.

Every other failed sign-in returns invalid_credentials, whatever the reason: an unknown institution or email, a wrong password, a deactivated or archived account, or any other account the app cannot serve. That answer never says which, so it never reveals whether an email is registered.

Sign-ins from the app

A sign-in from the app works only for the requests the app makes. Any other request made with it returns app_endpoint_unavailable; make that request with the institution’s secret key instead.

Unrecognised fields are rejected, not ignored

Send a field this API does not know and the request fails with the field named, rather than succeeding while quietly dropping your data. A typo in a field name is a loud error, which is the behaviour you want when the alternative is discovering months later that a column was never being saved.

One exception worth coding around

A 401 does not use the envelope above. It returns a plain-text reason. A client that assumes JSON on every error path will throw while handling the very case it was written for. Check the status before parsing, or guard the parse.

Every other status on this page returns the JSON error object.