Skip to main content

API Endpoints

Complete reference for all available SavvyMoney API endpoints.

Users

Enroll User

Enroll a new user in SavvyMoney. This must be done before accessing credit data.

POST /v1/users/enroll

Request Body:

{
"externalUserId": "user-12345",
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"ssn": "1234",
"dateOfBirth": "1985-06-15",
"address": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zipCode": "94102"
},
"phone": "+14155551234"
}
FieldTypeRequiredDescription
externalUserIdstringYesYour internal user ID
emailstringYesUser's email address
firstNamestringYesUser's first name
lastNamestringYesUser's last name
ssnstringYesLast 4 digits of SSN
dateOfBirthstringYesDate of birth (YYYY-MM-DD)
addressobjectYesUser's address
phonestringNoPhone number

Response:

{
"data": {
"userId": "usr_abc123xyz",
"externalUserId": "user-12345",
"status": "pending_verification",
"createdAt": "2024-01-15T10:30:00Z"
}
}

Get User

Retrieve user information.

GET /v1/users/{userId}

Response:

{
"data": {
"userId": "usr_abc123xyz",
"externalUserId": "user-12345",
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"status": "active",
"enrolledAt": "2024-01-15T10:30:00Z",
"lastScoreDate": "2024-01-15"
}
}

Delete User

Remove a user and their data from SavvyMoney.

DELETE /v1/users/{userId}

Response:

{
"data": {
"userId": "usr_abc123xyz",
"deletedAt": "2024-01-15T10:30:00Z",
"message": "User data will be permanently deleted within 30 days"
}
}

Credit Score

Get Credit Score

Retrieve the user's current credit score.

GET /v1/users/{userId}/credit-score

Response:

{
"data": {
"score": 742,
"scoreDate": "2024-01-15",
"scoreRange": {
"min": 300,
"max": 850
},
"rating": "Good",
"bureau": "Equifax",
"factors": [
{
"code": "PAYMENT_HISTORY",
"name": "Payment History",
"impact": "high",
"description": "Your payment history is excellent with no missed payments.",
"score": 95
},
{
"code": "CREDIT_UTILIZATION",
"name": "Credit Utilization",
"impact": "medium",
"description": "You're using 28% of your available credit.",
"score": 72,
"details": {
"utilizationPercent": 28,
"totalBalance": 4200,
"totalLimit": 15000
}
},
{
"code": "CREDIT_AGE",
"name": "Credit Age",
"impact": "medium",
"description": "Your average account age is 6 years.",
"score": 80,
"details": {
"averageAgeYears": 6,
"oldestAccountYears": 12
}
},
{
"code": "CREDIT_MIX",
"name": "Credit Mix",
"impact": "low",
"description": "You have a good mix of credit types.",
"score": 85
},
{
"code": "NEW_CREDIT",
"name": "New Credit Inquiries",
"impact": "low",
"description": "You have 1 recent inquiry.",
"score": 90,
"details": {
"recentInquiries": 1
}
}
],
"trend": {
"direction": "up",
"change": 12,
"period": "3months"
}
}
}

Get Score History

Retrieve historical credit scores.

GET /v1/users/{userId}/credit-score/history

Query Parameters:

ParameterTypeDefaultDescription
monthsinteger12Number of months of history
limitinteger25Max records to return

Response:

{
"data": [
{
"score": 742,
"date": "2024-01-15"
},
{
"score": 738,
"date": "2023-12-15"
},
{
"score": 730,
"date": "2023-11-15"
}
],
"pagination": {
"hasMore": true,
"total": 12
}
}

Offers

Get Offers

Retrieve personalized offers for a user.

GET /v1/users/{userId}/offers

Query Parameters:

ParameterTypeDefaultDescription
typestring-Filter by offer type (credit_card, loan, mortgage)
statusstringactiveOffer status
limitinteger25Max offers to return

Response:

{
"data": [
{
"offerId": "off_xyz789",
"type": "credit_card",
"provider": "Example Bank",
"name": "Rewards Plus Card",
"description": "Earn 2% cash back on all purchases",
"apr": {
"min": 15.99,
"max": 24.99,
"type": "variable"
},
"creditLimit": {
"min": 5000,
"max": 25000
},
"annualFee": 0,
"signupBonus": {
"amount": 200,
"requirement": "Spend $1,000 in first 3 months"
},
"preQualified": true,
"applicationUrl": "https://offers.savvymoney.com/apply/off_xyz789",
"expiresAt": "2024-02-15T23:59:59Z"
}
],
"pagination": {
"hasMore": false,
"total": 5
}
}

Track Offer Click

Record when a user clicks on an offer.

POST /v1/users/{userId}/offers/{offerId}/click

Request Body:

{
"source": "web",
"timestamp": "2024-01-15T10:30:00Z",
"metadata": {
"page": "dashboard",
"position": 1
}
}

Response:

{
"data": {
"clickId": "clk_abc123",
"offerId": "off_xyz789",
"userId": "usr_abc123xyz",
"recordedAt": "2024-01-15T10:30:00Z"
}
}

Alerts

Get Alerts

Retrieve credit monitoring alerts for a user.

GET /v1/users/{userId}/alerts

Query Parameters:

ParameterTypeDefaultDescription
statusstringallFilter: unread, read, all
typestring-Filter by alert type
limitinteger25Max alerts to return

Response:

{
"data": [
{
"alertId": "alt_def456",
"type": "score_change",
"title": "Your credit score increased",
"message": "Your credit score went up by 15 points to 742.",
"severity": "info",
"status": "unread",
"createdAt": "2024-01-15T10:30:00Z",
"data": {
"previousScore": 727,
"newScore": 742,
"change": 15
}
},
{
"alertId": "alt_ghi789",
"type": "new_inquiry",
"title": "New credit inquiry detected",
"message": "Example Bank checked your credit report.",
"severity": "warning",
"status": "unread",
"createdAt": "2024-01-14T08:00:00Z",
"data": {
"inquirySource": "Example Bank",
"inquiryDate": "2024-01-14"
}
}
]
}

Alert Types

TypeDescription
score_changeCredit score changed
new_inquiryNew credit inquiry
new_accountNew account opened
account_closedAccount closed
late_paymentLate payment reported
high_utilizationCredit utilization exceeded threshold
address_changeAddress change on file
fraud_alertPotential fraud detected

Mark Alert Read

Mark an alert as read.

PATCH /v1/users/{userId}/alerts/{alertId}

Request Body:

{
"status": "read"
}

Identity Verification

Get Verification Questions

Get identity verification questions for a user.

GET /v1/users/{userId}/verification/questions

Response:

{
"data": {
"sessionId": "ver_abc123",
"questions": [
{
"questionId": "q1",
"text": "Which of the following addresses have you lived at?",
"options": [
{ "id": "a", "text": "123 Main St, San Francisco, CA" },
{ "id": "b", "text": "456 Oak Ave, Los Angeles, CA" },
{ "id": "c", "text": "789 Pine Rd, Seattle, WA" },
{ "id": "d", "text": "None of the above" }
]
},
{
"questionId": "q2",
"text": "In which month did you open your account with Example Bank?",
"options": [
{ "id": "a", "text": "January" },
{ "id": "b", "text": "March" },
{ "id": "c", "text": "July" },
{ "id": "d", "text": "I don't have an account with Example Bank" }
]
}
],
"expiresAt": "2024-01-15T10:45:00Z"
}
}

Submit Verification Answers

Submit answers to verification questions.

POST /v1/users/{userId}/verification/answers

Request Body:

{
"sessionId": "ver_abc123",
"answers": [
{ "questionId": "q1", "answerId": "a" },
{ "questionId": "q2", "answerId": "b" }
]
}

Response:

{
"data": {
"verified": true,
"userId": "usr_abc123xyz",
"verifiedAt": "2024-01-15T10:32:00Z"
}
}

Batch Operations

Batch Enroll Users

Enroll multiple users in a single request.

POST /v1/users/enroll/batch

Request Body:

{
"users": [
{
"externalUserId": "user-001",
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"ssn": "1234",
"dateOfBirth": "1985-06-15",
"address": {
"street": "123 Main St",
"city": "San Francisco",
"state": "CA",
"zipCode": "94102"
}
},
{
"externalUserId": "user-002",
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Smith",
"ssn": "5678",
"dateOfBirth": "1990-03-22",
"address": {
"street": "456 Oak Ave",
"city": "Los Angeles",
"state": "CA",
"zipCode": "90001"
}
}
]
}

Response:

{
"data": {
"successful": [
{
"externalUserId": "user-001",
"userId": "usr_abc123",
"status": "pending_verification"
}
],
"failed": [
{
"externalUserId": "user-002",
"error": {
"code": "USER_EXISTS",
"message": "User already enrolled"
}
}
]
},
"meta": {
"total": 2,
"successful": 1,
"failed": 1
}
}

Error Responses

All endpoints may return these error responses:

400 Bad Request
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid request parameters",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
}
401 Unauthorized
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid or expired access token"
}
}
404 Not Found
{
"error": {
"code": "NOT_FOUND",
"message": "User not found"
}
}
429 Too Many Requests
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"retryAfter": 60
}
}

Next Steps