Skip to main content

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​

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.

FieldTypeRequiredDescription
fileFileYes*File to upload (multipart only)
file_urlStringYes*URL to file (JSON only)
file_nameStringNoName for the file (JSON only)
deal_idStringYesPipedrive deal ID
person_idStringYesPipedrive 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_url is missing in JSON mode.

2. /pipedrive/person​

POST: Finds or creates a person in Pipedrive.

FieldTypeRequiredDescription
search_termStringYesField to search by (e.g., email, phone)
search_valueStringYesValue to search for
first_nameStringNoPerson's first name
last_nameStringNoPerson's last name
nameStringNoFull name (split if first/last missing)
phoneStringNoPhone number (auto-formatted)
emailStringNoEmail address
...AnyNoAdditional 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_name missing but name provided, splits name.
  • 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.

FieldTypeRequiredDescription
search_termStringYesField to search by (e.g., name)
search_valueStringYesValue to search for
...AnyNoAdditional 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.

FieldTypeRequiredDescription
...AnyYesArbitrary deal fields
noteStringNoNote 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 note and label.
  • 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_date is provided, extracts due_date and due_time.

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 of plain_body or html_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: /register or /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.com
    • https://portal.morfinancial.com
    • https://morminds.com
    • https://api.morminds.com
  • CORS Preflight: Handles OPTIONS requests 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.