MOR Financial Serverless API Documentation
Overviewβ
This document provides a comprehensive reference for the serverless API defined in serverless.js. It covers all endpoints, handlers, utility functions, authentication, edge cases, and error handling. The API is designed to interact with Pipedrive, Documentero, and a custom pricing engine, as well as to handle user authentication and email sending.
Table of Contentsβ
- Authentication
- Endpoints
- Admin Endpoints
- Utility & Helper Functions
- Edge Cases & Error Handling
- CORS & Security
- Deprecated & Advanced Functions
Authenticationβ
All endpoints require user authentication via a Bearer token in the Authorization header. Tokens are validated against a KV store. If the token is missing or invalid, the request is rejected with a 403 Forbidden or Invalid token error.
Example:
Authorization: Bearer <API_KEY>
Endpointsβ
Pipedrive Endpointsβ
All endpoints under /pipedrive/* require authentication and interact with the Pipedrive API.
1. /pipedrive/fileuploadβ
POST: Uploads a file to Pipedrive, either via multipart form-data or by providing a file URL in JSON.
| Field | Type | Required | Description |
|---|---|---|---|
| file | File | Yes* | File to upload (multipart only) |
| file_url | String | Yes* | URL to file (JSON only) |
| file_name | String | No | Name for the file (JSON only) |
| deal_id | String | Yes | Pipedrive deal ID |
| person_id | String | Yes | Pipedrive person ID |
*One of file (multipart) or file_url (JSON) is required.
Sample Request (multipart):
POST /pipedrive/fileupload
Authorization: Bearer <API_KEY>
Content-Type: multipart/form-data
file: <file>
deal_id: 123
person_id: 456
Sample Request (JSON):
POST /pipedrive/fileupload
Authorization: Bearer <API_KEY>
Content-Type: application/json
{
"file_url": "https://example.com/file.pdf",
"file_name": "file.pdf",
"deal_id": "123",
"person_id": "456"
}
Sample Response:
{
"message": "File uploaded successfully"
}
Status Codes:
- 200: Success
- 400: Missing required fields or invalid file
- 403: Unauthorized
- 500: Upstream Pipedrive error
Error Example:
{
"error": "Missing required field: file_url"
}
Edge Cases:
- Throws error if file is missing or invalid.
- Throws error if
file_urlis missing in JSON mode.
2. /pipedrive/personβ
POST: Finds or creates a person in Pipedrive.
| Field | Type | Required | Description |
|---|---|---|---|
| search_term | String | Yes | Field to search by (e.g., email, phone) |
| search_value | String | Yes | Value to search for |
| first_name | String | No | Person's first name |
| last_name | String | No | Person's last name |
| name | String | No | Full name (split if first/last missing) |
| phone | String | No | Phone number (auto-formatted) |
| String | No | Email address | |
| ... | Any | No | Additional Pipedrive person fields |
Sample Request:
POST /pipedrive/person
Authorization: Bearer <API_KEY>
Content-Type: application/json
{
"search_term": "email",
"search_value": "john@example.com",
"name": "John Doe",
"phone": "(555) 123-4567"
}
Sample Response:
{
"id": 789,
"name": "John Doe",
"email": "john@example.com",
...
}
Status Codes:
- 200: Success
- 400: Missing required fields
- 403: Unauthorized
- 500: Upstream Pipedrive error
Error Example:
{
"error": "Missing required fields: search_term, search_value"
}
Edge Cases:
- If
first_name/last_namemissing butnameprovided, splitsname. - Phone numbers are formatted to E.164.
- Returns first match if found, otherwise creates a new person.
3. /pipedrive/organizationβ
POST: Finds or creates an organization in Pipedrive.
| Field | Type | Required | Description |
|---|---|---|---|
| search_term | String | Yes | Field to search by (e.g., name) |
| search_value | String | Yes | Value to search for |
| ... | Any | No | Additional Pipedrive organization fields |
Sample Request:
POST /pipedrive/organization
Authorization: Bearer <API_KEY>
Content-Type: application/json
{
"search_term": "name",
"search_value": "Acme Corp"
}
Sample Response:
{
"id": 321,
"name": "Acme Corp",
...
}
Status Codes:
- 200: Success
- 400: Missing required fields
- 403: Unauthorized
- 500: Upstream Pipedrive error
Error Example:
{
"error": "Missing required fields: search_term, search_value"
}
Edge Cases:
- Returns first match if found, otherwise creates a new organization.
4. /pipedrive/dealβ
POST: Creates a new deal in Pipedrive.
| Field | Type | Required | Description |
|---|---|---|---|
| ... | Any | Yes | Arbitrary deal fields |
| note | String | No | Note to attach to the deal |
Sample Request:
POST /pipedrive/deal
Authorization: Bearer <API_KEY>
Content-Type: application/json
{
"title": "New Deal",
"person_id": "789",
"organization_id": "321",
"value": "100000",
"note": "Urgent deal"
}
Sample Response:
{
"id": 555,
"title": "New Deal",
...
}
Status Codes:
- 200: Success
- 400: Missing required fields
- 403: Unauthorized
- 500: Upstream Pipedrive error
Error Example:
{
"error": "Pipedrive API Error: ..."
}
Edge Cases:
- Transforms enums/sets to option IDs.
- Transforms monetary fields to numbers and adds currency.
- Skips empty fields.
- Attaches note if provided.
5. /pipedrive/updatedealβ
POST: Updates an existing deal in Pipedrive.
- Required field:
dealId - Payload: Arbitrary deal fields, plus optional
note. - Edge Cases:
- Same transformation logic as deal creation.
- Attaches note if provided.
6. /pipedrive/leadβ
POST: Creates a new lead in Pipedrive.
- Payload: Arbitrary lead fields, plus optional
noteandlabel. - Edge Cases:
- Transforms enums/sets, monetary, date, and label fields.
- Skips empty fields.
- Attaches note if provided.
7. /pipedrive/updateleadβ
POST: Updates an existing lead in Pipedrive.
- Required field:
leadId - Payload: Arbitrary lead fields, plus optional
label. - Edge Cases:
- Same transformation logic as lead creation.
- Skips empty fields.
8. /pipedrive/listdealsβ
POST: Lists all deals for a person.
- Required field:
person_id
9. /pipedrive/listactivitiesβ
POST: Lists all activities for a deal.
- Required field:
deal_id
10. /pipedrive/searchuserβ
POST: Searches for a person by email.
- Required field:
email
11. /pipedrive/addactivityβ
POST: Adds an activity to Pipedrive.
- Required fields:
subject,type - Optional fields:
deal_id,person_id,start_date,due_date,due_time,note - Edge Cases:
- If
start_dateis provided, extractsdue_dateanddue_time.
- If
12. /pipedrive/itemsearchβ
POST: Searches for items in Pipedrive.
- Required fields:
term,item_type
Engine Endpointsβ
1. /engine/priceβ
POST: Calculates pricing options based on loan and property data.
- Required fields:
loanAmount,propertyValue,loanTerm,creditScore,ltv - Optional fields:
transactionType,loanType,propertyType,propertySubType,morFundingExperience,repeatClient,fundingPmts,nodNosThreeYears,mtgBroker - Returns: Array of pricing options with rate, funding fee, payment, admin fee, and description.
- Edge Cases:
- Returns error if required fields are missing.
Other Endpointsβ
1. /docβ
POST: Generates a document using Documentero and uploads it to Pipedrive.
- Required fields:
template,template_name,deal_id,person_id - Edge Cases:
- Throws error if required fields are missing.
- Filters out undefined template data.
2. /mailβ
POST: Sends an email via Postal SMTP server.
- Required fields:
to,sender,subject, and at least one ofplain_bodyorhtml_body - Optional fields:
cc,bcc,reply_to,attachments - Edge Cases:
- Handles both file URLs and blobs for attachments.
Admin Endpointsβ
1. /<ACCESS_TOKEN>/*β
- DELETE:
/userβ Deletes a user. - POST:
/registeror/resetβ Registers or resets a user, returns a new API key. - Edge Cases:
- Throws error if user not found or invalid action.
Utility & Helper Functionsβ
- Document Generation: Uses Documentero API, filters out undefined fields.
- File Uploads: Handles both direct file and URL-based uploads.
- Person/Organization Search: Searches by term/value, creates if not found.
- Deal/Lead Creation & Update: Transforms enums, sets, monetary, date, and label fields. Skips empty fields. Handles notes.
- Activity Management: Adds and lists activities for deals.
- Email Sending: Handles attachments as URLs or blobs.
- Phone Formatting: Converts to E.164 format.
- Date/Time: Uses Los Angeles timezone for all date/time formatting.
- Label Mapping: Maps common label aliases to Pipedrive label IDs.
Edge Cases & Error Handlingβ
- Missing Fields: Most endpoints return a 400 error with a descriptive message if required fields are missing.
- Invalid Data: Returns 400 or 500 errors for invalid data or failed API calls.
- Pipedrive/Documentero/Postal Errors: Returns error messages from upstream APIs.
- Empty/Null/Undefined Fields: Skipped in payloads to avoid validation errors.
- Special Label/Enum Handling: Maps common aliases and handles case-insensitive matching.
- CORS: Only allows requests from whitelisted origins.
CORS & Securityβ
- Allowed Origins:
https://www.morfinancial.comhttps://portal.morfinancial.comhttps://morminds.comhttps://api.morminds.com
- CORS Preflight: Handles
OPTIONSrequests and sets appropriate headers. - Authorization: All endpoints require a valid Bearer token.
Deprecated & Advanced Functionsβ
- transformMonetaryFields: Legacy function for transforming currency fields.
- generateLeadTitle: Generates a lead title from address or name.
- validateAndTransformIds: Ensures numeric IDs are valid.
- transformSingleValueFields: Maps enums/sets to option IDs.
- transformLeadData: Advanced transformation for lead payloads, including special mapping for lead source fields.
Security Notesβ
- All requests and responses are logged for auditing purposes (except sensitive data).
- API keys should be kept secret and rotated regularly.
- Data is only stored temporarily for processing; no long-term storage of sensitive information.
- All external API calls are made over HTTPS.
- No rate limiting is currently enforced, but clients are expected to use reasonable request rates. (Enterprise deployments may add rate limiting at the gateway or proxy level.)
- All error messages are sanitized to avoid leaking sensitive information.
Rate Limiting/Throttlingβ
- No built-in rate limiting in this API layer. For production/enterprise deployments, it is recommended to use an API gateway or reverse proxy to enforce rate limits and protect backend resources.
Error Response Formatβ
All error responses are JSON with an error field, except for some admin endpoints which may return plain text.
Example:
{
"error": "Missing required field: deal_id"
}
Notesβ
- All API calls are asynchronous and expect JSON request/response bodies unless otherwise noted.
- All date/time values are handled in Los Angeles timezone.
- All monetary values are assumed to be in USD unless specified.
- The API is designed to be robust against missing/invalid fields and to provide clear error messages for all edge cases.