Mailed Records API
Customer-facing reference for Ratespedia's Mailed Records API. Use this guide to configure authentication, test your client safely, search approved mailed-record results, update approved contact fields, and handle every expected response.
Overview
The API gives approved customers a controlled way to search mailed-record results and update contact details used in follow-up workflows. It supports two customer access paths:
- Direct API access for server-side integrations.
- The Mailed Records Portal for browser-based teams that should not handle API keys.
Canonical routes:
API docs: /partners/mailed-records-api
Portal: /partners/mailed-records-portal
Base URL
https://www.ratespedia.com
Customer Setup Flow
- Request customer API access from Ratespedia.
- Store your API key only on your server.
- Run the configuration test endpoints first.
- Confirm your client handles success, validation errors, authentication errors, quota errors, and service errors.
- Switch to the production endpoints.
- Use pagination for production search results.
- Use contact updates only for approved owner contact and consent fields.
Environments And Endpoints
Configuration tests return deterministic responses and do not read or update production records.
| Environment | Method | Path | Purpose |
|---|---|---|---|
| Test | GET | /api/mailed-records/test/search | Validate headers, filters, pagination handling, and error handling. |
| Test | PATCH | /api/mailed-records/test/contact | Validate headers, JSON body shape, contact-field validation, and error handling. |
| Production | GET | /api/mailed-records/search | Search approved mailed-record results. |
| Production | PATCH | /api/mailed-records/contact | Update approved owner contact and consent fields. |
Authentication
Direct API requests require one API key. Send it with either supported header.
Recommended:
Authorization: Bearer <token>
Also supported:
x-api-key: <token>
Do not send both headers in the same request. Do not place API keys in browser code, URLs, screenshots, or client-side logs.
Configuration Test Endpoints
Use the test endpoints during initial setup, credential rotation, and client changes. They validate request shape without touching production records.
Test responses include:
{
"test": {
"mode": "configuration_test",
"header": "Authorization",
"tokenPreview": "test...1234",
"credentialValidated": false,
"productionDataTouched": false
}
}
credentialValidated: false means the test endpoint accepted the header format but did not verify that the key is active for production. Production endpoints validate the actual key.
Test Search
GET /api/mailed-records/test/search
Example:
curl -H "Authorization: Bearer $RATESPEDIA_API_KEY" \
"https://www.ratespedia.com/api/mailed-records/test/search?state=TX&query=Main%20Street&limit=25"
Successful response:
{
"success": true,
"test": {
"mode": "configuration_test",
"header": "Authorization",
"tokenPreview": "test...1234",
"credentialValidated": false,
"productionDataTouched": false
},
"items": [
{
"mailedRecordId": "11111111-1111-4111-8111-111111111111",
"reference": "TEST-REF-0001",
"mailhouseRef": "TEST-REF-0001",
"owner": {
"firstName": "Jordan",
"lastName": "Sample",
"address": "100 Owner Example Way",
"city": "Austin",
"state": "TX",
"zip": "78701",
"email": "jordan.sample@example.com",
"phone": "+1 512-555-0199",
"optInLanguage": "Configuration test consent language.",
"trustedFormCertUrl": "https://cert.trustedform.com/example-test-certificate"
},
"property": {
"address": "200 Property Example Ave",
"city": "Austin",
"state": "TX",
"zip": "78701",
"zip4": null,
"type": "SFR",
"marketValue": 425000,
"purchasePrice": 315000,
"lengthOfOwnership": 6
},
"loan": {
"amount": 280000,
"rate": 3.625,
"lender": "Configuration Test Lender",
"originationDate": "2021-02-01",
"type": "CONVENTIONAL",
"loanToValue": 65.9,
"veteranInHousehold": false
}
}
],
"pageInfo": {
"limit": 25,
"returned": 1,
"hasNextPage": true,
"nextCursor": "opaque-test-token"
},
"appliedFilters": {
"query": "Main Street",
"state": "TX",
"limit": 25,
"hasCursor": false
}
}
Test Contact Update
PATCH /api/mailed-records/test/contact
Example:
curl -X PATCH \
-H "Authorization: Bearer $RATESPEDIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mailedRecordId": "11111111-1111-4111-8111-111111111111",
"ownerEmail": "updated@example.com",
"ownerPhone": "+1 555-555-0199",
"optInLanguage": "Configuration test consent language.",
"trustedFormCertUrl": "https://cert.trustedform.com/example-test-certificate"
}' \
"https://www.ratespedia.com/api/mailed-records/test/contact"
Successful response:
{
"success": true,
"test": {
"mode": "configuration_test",
"header": "Authorization",
"tokenPreview": "test...1234",
"credentialValidated": false,
"productionDataTouched": false
},
"item": {
"mailedRecordId": "11111111-1111-4111-8111-111111111111",
"ownerEmail": "updated@example.com",
"ownerPhone": "+1 555-555-0199",
"optInLanguage": "Configuration test consent language.",
"trustedFormCertUrl": "https://cert.trustedform.com/example-test-certificate",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
}
Forced Test Scenarios
Use scenario to confirm your error handling before production traffic.
| Scenario | Test search | Test contact | Response |
|---|---|---|---|
ok | Yes | Yes | Normal success response. |
empty | Yes | No | Search success with no items. |
invalid_api_key | Yes | Yes | 401 invalid_api_key. |
rate_limited | Yes | Yes | 429 rate_limited. |
daily_quota_exceeded | Yes | Yes | 429 daily_quota_exceeded. |
record_not_found | No | Yes | 404 record_not_found. |
server_error | Yes | Yes | 500 search_failed or 500 contact_update_failed. |
Example:
curl -H "Authorization: Bearer $RATESPEDIA_API_KEY" \
"https://www.ratespedia.com/api/mailed-records/test/search?scenario=rate_limited"
Production Search
GET /api/mailed-records/search
Purpose: search approved mailed-record results with filters and cursor pagination.
Query Parameters
| Parameter | Type | Required | Notes |
|---|---|---|---|
query | string | No | General search text for names, addresses, or broad narrowing. Maximum 120 characters. |
reference | string | No | Reference lookup. Maximum 120 characters. |
address | string | No | Property-address lookup. Maximum 160 characters. |
state | string | No | Two-letter property state abbreviation. |
city | string | No | Property city. Maximum 80 characters. |
zip | string | No | Five-digit property ZIP code. |
loanType | string | No | Loan type filter. Maximum 40 characters. |
minMarketValue | number | No | Minimum property market value. |
maxMarketValue | number | No | Maximum property market value. |
minLoanAmount | number | No | Minimum first mortgage amount. |
maxLoanAmount | number | No | Maximum first mortgage amount. |
veteranInHousehold | boolean | No | true or false. |
limit | integer | No | Page size. Defaults to 25; maximum is normally 50. |
cursor | string | No | Opaque cursor from pageInfo.nextCursor. |
Production Search Example
curl -H "Authorization: Bearer $RATESPEDIA_API_KEY" \
"https://www.ratespedia.com/api/mailed-records/search?state=TX&query=Main%20Street&limit=25"
Production Search Response
{
"success": true,
"items": [
{
"mailedRecordId": "uuid",
"reference": "ABC123",
"mailhouseRef": "ABC123",
"owner": {
"firstName": "Jane",
"lastName": "Doe",
"address": "123 Owner St",
"city": "Dallas",
"state": "TX",
"zip": "75001",
"email": "jane@example.com",
"phone": "+1 555-555-0100",
"optInLanguage": "Customer consent language.",
"trustedFormCertUrl": "https://cert.trustedform.com/example"
},
"property": {
"address": "456 Property Ave",
"city": "Dallas",
"state": "TX",
"zip": "75001",
"zip4": null,
"type": "SFR",
"marketValue": 450000,
"purchasePrice": 320000,
"lengthOfOwnership": 7
},
"loan": {
"amount": 280000,
"rate": 3.625,
"lender": "Example Bank",
"originationDate": "2021-02-01",
"type": "CONVENTIONAL",
"loanToValue": 62.2,
"veteranInHousehold": false
}
}
],
"pageInfo": {
"limit": 25,
"returned": 25,
"hasNextPage": true,
"nextCursor": "opaque-token"
},
"appliedFilters": {
"query": "Main Street",
"state": "TX",
"limit": 25,
"hasCursor": false
}
}
Pagination
Search uses cursor pagination.
- Read
pageInfo.hasNextPage. - If it is
true, passpageInfo.nextCursoras the next request'scursor. - Treat cursors as opaque. Do not parse, edit, or store them as business identifiers.
- Keep the same filters when requesting the next page.
Production Contact Update
PATCH /api/mailed-records/contact
Purpose: update approved contact and consent fields for a mailed record.
Request Body
| Field | Type | Required | Notes |
|---|---|---|---|
mailedRecordId | UUID string | Yes | Record ID from search response. |
ownerEmail | string or null | No | Owner email. Must be valid when present. |
ownerPhone | string | Yes | Owner phone. Must be a valid US phone number. |
optInLanguage | string or null | No | Consent or opt-in language. Maximum 2,000 characters. |
trustedFormCertUrl | HTTPS URL string or null | No | TrustedForm certificate URL. Must be HTTPS. |
At least one update field must be supplied. Current contact saves require ownerPhone.
Production Contact Example
curl -X PATCH \
-H "Authorization: Bearer $RATESPEDIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mailedRecordId": "00000000-0000-0000-0000-000000000000",
"ownerEmail": "updated@example.com",
"ownerPhone": "+1 555-555-0199",
"optInLanguage": "Customer requested follow-up by phone.",
"trustedFormCertUrl": "https://cert.trustedform.com/example"
}' \
"https://www.ratespedia.com/api/mailed-records/contact"
Production Contact Response
{
"success": true,
"item": {
"mailedRecordId": "00000000-0000-0000-0000-000000000000",
"ownerEmail": "updated@example.com",
"ownerPhone": "+1 555-555-0199",
"optInLanguage": "Customer requested follow-up by phone.",
"trustedFormCertUrl": "https://cert.trustedform.com/example",
"updatedAt": "2026-01-01T00:00:00.000Z"
}
}
Portal Access
Customers who need browser access can use:
/partners/mailed-records-portal
Use the portal when your team needs lookup and contact-update access without handling API keys. Ratespedia will provide the customer login or setup instructions separately.
Error Format
All API errors use this JSON shape:
{
"success": false,
"error": "Human-readable message.",
"code": "machine_readable_code"
}
Some errors may include a details object when safe to expose.
Status Codes
| Status | Meaning |
|---|---|
200 | Request succeeded. |
400 | Request is malformed or failed validation. |
401 | API key or portal authentication is missing or invalid. |
404 | Contact update target was not found. |
429 | Rate limit or quota was exceeded. |
500 | Service configuration or temporary service failure. |
Error Codes
| Code | Status | What to do |
|---|---|---|
missing_api_key | 401 | Send Authorization: Bearer <token> or x-api-key: <token>. |
invalid_api_key | 401 | Confirm the key with Ratespedia and retry with the correct environment. |
ambiguous_authentication | 400 | Send only one supported auth header. |
invalid_authorization_header | 401 | Use Authorization: Bearer <token>. |
invalid_json | 400 | Send valid JSON with Content-Type: application/json. |
invalid_body | 400 | Send a JSON object. |
invalid_parameter | 400 | Shorten text filters to the documented limits. |
invalid_zip | 400 | Use a five-digit ZIP code. |
invalid_number | 400 | Use non-negative numeric filter values. |
invalid_boolean | 400 | Use true or false. |
invalid_integer | 400 | Use a valid page-size integer. |
invalid_cursor | 400 | Restart pagination from the first page. |
invalid_range | 400 | Make sure minimum filters do not exceed maximum filters. |
invalid_record_id | 400 | Use a valid mailedRecordId from search results. |
missing_contact_fields | 400 | Include at least one approved update field. |
missing_owner_phone | 400 | Include a valid ownerPhone. |
invalid_email | 400 | Send a valid email address or null. |
invalid_phone | 400 | Send a valid US phone number. |
invalid_contact_text | 400 | Send text fields as strings or null, within length limits. |
invalid_trusted_form_cert_url | 400 | Send a valid HTTPS TrustedForm certificate URL. |
record_not_found | 404 | Confirm the record still exists and the ID came from search results. |
rate_limited | 429 | Retry after at least one minute. |
daily_quota_exceeded | 429 | Wait for the next quota window or contact Ratespedia. |
weekly_quota_exceeded | 429 | Wait for the next quota window or contact Ratespedia. |
monthly_quota_exceeded | 429 | Wait for the next quota window or contact Ratespedia. |
search_failed | 500 | Retry later. Contact Ratespedia if it persists. |
contact_update_failed | 500 | Retry later. Contact Ratespedia if it persists. |
unexpected_error | 500 | Retry later. Contact Ratespedia if it persists. |
Rate Limits And Quotas
Ratespedia enforces short-term rate limits and longer quota windows. Exact customer limits are assigned during onboarding.
Default behavior commonly used by the API:
| Limit type | Default |
|---|---|
| Search rate limit | 60 requests per minute |
| Contact update rate limit | 20 requests per minute |
| Default search page size | 25 |
| Maximum search page size | 50 |
If you receive 429, slow your request rate and retry later. If you consistently hit quota limits, contact Ratespedia to review your plan.
Customer Go-Live Checklist
- Confirm you have the correct production base URL.
- Store the API key server-side only.
- Run
GET /api/mailed-records/test/searchwith your client. - Run
PATCH /api/mailed-records/test/contactwith your client. - Force test scenarios for
401,400,404,429, and500handling. - Switch your client to production search.
- Confirm production pagination handling with
pageInfo.nextCursor. - Confirm production contact update behavior on an approved test record from Ratespedia.
- Keep request and response logs that redact API keys and personal data.
Troubleshooting
| Symptom | Checks |
|---|---|
401 on test endpoints | Confirm the auth header exists and uses a supported format. |
401 on production endpoints | Confirm the API key is active and belongs to the production environment. |
400 on search | Check parameter names, ZIP format, numeric filters, booleans, and cursor freshness. |
400 on contact update | Check JSON syntax, UUID format, phone format, email format, and TrustedForm HTTPS URL. |
| Empty production search results | Broaden filters or confirm the expected records are available to your account. |
429 responses | Reduce request rate or contact Ratespedia about quota. |
| Contact update does not appear | Confirm the PATCH returned success: true, then search the same record again. |
Support
For access, quota changes, production test records, or integration support, contact Ratespedia through /partners/contact.