API Overview
The SavvyMoney API is a RESTful API that provides programmatic access to credit scores, user management, and personalized offers.
Base URLs
| Environment | Base URL |
|---|---|
| Sandbox | https://api.sandbox.savvymoney.com |
| Production | https://api.savvymoney.com |
Always use sandbox for development and testing. Production credentials should only be used in your production environment with real user data.
API Versioning
The API uses URL path versioning. The current version is v1.
https://api.savvymoney.com/v1/users
When we release breaking changes, we'll increment the version number. Previous versions will be supported for at least 12 months after deprecation notice.
Authentication
All API requests require authentication using OAuth 2.0 Bearer tokens.
curl -X GET "https://api.savvymoney.com/v1/users/{userId}/credit-score" \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json"
See Authentication for details on obtaining tokens.
Request Format
Headers
All requests should include these headers:
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token: Bearer {access_token} |
Content-Type | Yes (for POST/PUT) | application/json |
Accept | Recommended | application/json |
X-Request-ID | Recommended | Unique request identifier for tracing |
Request Body
For POST and PUT requests, send JSON in the request body:
{
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
}
Response Format
Success Responses
Successful responses return JSON with appropriate HTTP status codes:
{
"data": {
"userId": "usr_abc123",
"score": 742,
"scoreDate": "2024-01-15"
},
"meta": {
"requestId": "req_xyz789",
"timestamp": "2024-01-15T10:30:00Z"
}
}
HTTP Status Codes
| Code | Description |
|---|---|
200 | Success |
201 | Created |
204 | No Content (successful delete) |
400 | Bad Request - Invalid parameters |
401 | Unauthorized - Invalid or expired token |
403 | Forbidden - Insufficient permissions |
404 | Not Found - Resource doesn't exist |
409 | Conflict - Resource already exists |
422 | Unprocessable Entity - Validation error |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error |
503 | Service Unavailable |
Error Responses
Errors return a consistent JSON structure:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "The request could not be validated",
"details": [
{
"field": "email",
"message": "Invalid email format"
}
]
},
"meta": {
"requestId": "req_xyz789",
"timestamp": "2024-01-15T10:30:00Z"
}
}
Error Codes
| Code | Description |
|---|---|
VALIDATION_ERROR | Request validation failed |
AUTHENTICATION_ERROR | Invalid credentials or token |
AUTHORIZATION_ERROR | Insufficient permissions |
NOT_FOUND | Resource not found |
RATE_LIMIT_EXCEEDED | Too many requests |
USER_NOT_ENROLLED | User must be enrolled first |
CREDIT_FROZEN | User's credit is frozen |
INTERNAL_ERROR | Server error - contact support |
Rate Limits
API requests are subject to rate limiting:
| Endpoint Type | Limit | Window |
|---|---|---|
| Authentication | 100 requests | 1 minute |
| User Operations | 1000 requests | 1 minute |
| Batch Operations | 50 requests | 1 minute |
| Webhooks | Unlimited | - |
Rate limit headers are included in every response:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1705312800
When rate limited, you'll receive a 429 response:
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please retry after 60 seconds.",
"retryAfter": 60
}
}
Pagination
List endpoints support pagination using cursor-based pagination:
GET /v1/users?limit=25&cursor=eyJpZCI6MTAwfQ
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 25 | Items per page (max 100) |
cursor | string | - | Cursor from previous response |
Paginated responses include pagination metadata:
{
"data": [...],
"pagination": {
"hasMore": true,
"nextCursor": "eyJpZCI6MTI1fQ",
"total": 250
}
}
Filtering & Sorting
Many list endpoints support filtering and sorting:
GET /v1/offers?status=active&sort=-createdAt
Common Filters
| Parameter | Description |
|---|---|
status | Filter by status |
createdAfter | Created after date (ISO 8601) |
createdBefore | Created before date (ISO 8601) |
Sorting
Use the sort parameter with field names. Prefix with - for descending order:
sort=createdAt # Ascending
sort=-createdAt # Descending
sort=score,-date # Multiple fields
Idempotency
For POST requests that create resources, you can provide an idempotency key to prevent duplicate operations:
curl -X POST "https://api.savvymoney.com/v1/users/enroll" \
-H "Authorization: Bearer {token}" \
-H "Idempotency-Key: unique-request-id-123" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", ...}'
If you retry a request with the same idempotency key within 24 hours, you'll receive the original response.
SDKs & Libraries
While you can call the API directly, we provide official SDKs:
| Language | Package |
|---|---|
| JavaScript/Node.js | npm install @savvymoney/node-sdk |
| Java | Maven: com.savvymoney:sdk |
| Python | pip install savvymoney |
| iOS | CocoaPods: SavvyMoneySDK |
| Android | Gradle: com.savvymoney:sdk |
API Changelog
v1.2.0 (2024-01-15)
- Added batch enrollment endpoint
- Improved error messages
- Added
X-Request-IDheader support
v1.1.0 (2023-10-01)
- Added webhook support
- Added offer click tracking
- Performance improvements
v1.0.0 (2023-06-01)
- Initial release
Next Steps
- Set up Authentication
- Explore API Endpoints
- Configure Webhooks