Open To Close TC Platform Hub

Open To Close (OTC) is the Transaction Coordinator (TC) platform for RERI’s real estate deal management. This hub covers the OTC REST API, authentication pattern, property/transaction lifecycle, contact management, and HubSpot deal-ID association. Read before writing any TC automation, document upload, or deal status sync. Every OTC API call references a HubSpot deal-id — the two systems are tightly coupled; OTC is the TC operational layer, HubSpot is the CRM source of truth.

Quick reference

FieldValue
VendorOpen To Close
URLhttps://app.opentoclose.com / https://api.opentoclose.com/v1
KB docAPI
Auth methodAPI key via query string (?api_token=TOKEN)
Auth credentialop://Aurora/opentoclose/api-token
Cred-proxy portn/a (until B1-B6 ratified per nemoclaw-audit-2026-05-03)
Webhook portn/a (webhooks not documented in API; use Zapier integration for event triggers)
Webhook handlern/a
Webhook dedup tablen/a
Tunnel pathn/a
Outbound API basehttps://api.opentoclose.com/v1
Rate limits1 request per second (429 on exceed)
Rate-limit action429 → 1s sleep + retry (3 retries), Discord ops alert
Paginationoffset (default 0) + limit (default 20, max 100); Properties max 50/call
Total endpoints37 across 18 resource groups
CostSubscription (SaaS); no per-call API cost
Backup/recoveryOTC-owned SaaS; Supabase sync for deal state mirror
Discord alert channelops
Drift cadenceon-API-change; manual
Data licensesubscription — active OTC account required
Statusproduction

⚠️ Auth: query string token, NOT Bearer header

OTC uses ?api_token=TOKEN in the query string — NOT an Authorization: Bearer header. This is a common foot-gun. The previous (fabricated) KB docs had this wrong. Always append ?api_token=<TOKEN> to every request URL.

# Correct
curl "https://api.opentoclose.com/v1/properties?api_token=YOUR_TOKEN&limit=10"
 
# Wrong (will 403)
curl "https://api.opentoclose.com/v1/properties" -H "Authorization: Bearer YOUR_TOKEN"

Token is retrieved from: op://Aurora/opentoclose/api-token


⚠️ HubSpot deal-id association: mandatory

Every OTC property (deal/transaction) must be associated with a HubSpot deal-id. The api_data field on OTC Properties carries external IDs (Follow Up Boss, Dotloop, Brokermint, SkySlope). When creating or updating an OTC property:

  1. Retrieve the HubSpot deal-id from hubspot (acq pipeline 877963314 or dispo 816046)
  2. Store the OTC property id back on the HubSpot deal in a custom property (e.g., otc_property_id)
  3. All downstream OTC calls use the OTC property id; all CRM queries use the HubSpot deal-id
  4. Without this association, TC workflow events cannot be linked back to the deal pipeline

Data model: Properties are key-value based

OTC “Properties” are the core transaction/deal objects (NOT real estate properties). They use a dynamic field_values array — not fixed columns:

{
  "id": 1,
  "field_values": [
    {"key": "contract_title", "value": "123 Main St, Riverside CA 92501", "type": "text"},
    {"key": "contract_status", "value": "Pending", "type": "choice"},
    {"key": "property_address", "value": "123 Main St"},
    {"key": "property_city", "value": "Riverside"},
    {"key": "property_state", "value": "CA"},
    {"key": "property_zip", "value": "92501"}
  ]
}

When updating: use PATCH /v1/properties/:id with {"field_identifier": "key", "fields": [{"key": "...", "value": "..."}]}


Components

  • workspace/knowledge-base/opentoclose/API.md — Full REST API reference (37 endpoints, verified 2026-03-17 live scrape)
  • workspace/knowledge-base/opentoclose/raw-collection.json — Raw Postman collection (260KB)
  • workspace/knowledge-base/opentoclose/endpoints-parsed.json — Machine-parseable endpoint list (91KB)
  • https://app.opentoclose.com — TC platform UI
  • https://api.opentoclose.com/v1 — REST API base

Key endpoints

MethodEndpointDescription
GET/v1/propertiesList all deals (max 50/call)
GET/v1/properties/:idGet single deal
POST/v1/properties/Create new deal (requires team_member_id, agent_id, time_zone_id, property_template_id)
PATCH/v1/properties/:idUpdate deal field values
GET/v1/properties/:id/contactsGet contacts on deal
POST/v1/properties/:id/contactsAssociate contact + role to deal
POST/v1/properties/:id/documentsUpload document (base64-encoded; types: pdf, doc, docx, jpg, png, xls, csv, xlsx, zip)
GET/v1/properties/:id/notesList deal notes
POST/v1/properties/:id/notesCreate note (pinned, private, priority)
GET/v1/propertyFieldsList all dynamic field definitions
GET/v1/teams/List teams + members (needed for property creation)
GET/v1/propertyTemplates/List templates (needed for property creation)
GET/v1/timeZonesList time zones (needed for property creation)

How it’s used

  • TC workflow creation: When a deal passes acq gate, create OTC property using HubSpot deal-id reference; assign to TC team member
  • Document management: Upload signed contracts, disclosures, and TC deliverables via POST /v1/properties/:id/documents (base64-encoded)
  • Deal status sync: PATCH contract_status field as deal moves through TC stages; mirror to HubSpot deal stage via betterfiles-dispo-emails
  • Contact association: Attach buyer, seller, title, escrow contacts per deal using POST /v1/properties/:id/contacts with appropriate contact_role_id
  • Failure mode: 403 = wrong auth method (use query string, not header); 429 = rate limit (1 req/sec — add 1s delay in loops); 409 conflict on duplicate contact
  • Success criteria: OTC property created and linked to HubSpot deal within 5 min of deal approval; TC notes and docs visible in OTC UI

Pagination pattern

// OTC pagination: offset + limit (not page-based)
async function getAllOtcProperties(apiToken) {
  let offset = 0;
  const limit = 50; // max for properties
  const all = [];
 
  while (true) {
    const res = await fetch(
      `https://api.opentoclose.com/v1/properties?api_token=${apiToken}&offset=${offset}&limit=${limit}`
    );
    const batch = await res.json();
    all.push(...batch);
    if (batch.length < limit) break;
    offset += limit;
    await new Promise(r => setTimeout(r, 1100)); // rate limit: 1 req/sec
  }
  return all;
}

Agents that touch this

  • _summary — deal coordination, TC handoff
  • _summary — triggers OTC property creation on deal approval
  • _summary — updates OTC deal status on buyer selection

Skills that invoke this

Plans that govern this

Feedback rules

KB / source docs

  • API — verified REST API reference (live scrape 2026-03-17); endpoints-parsed.json for machine-readable schema

System maps


PlatformHubRole
CRMLScrmlsMLS listing source
PropStreampropstreamFlipper lead lists
OpenToClose (this hub)opentocloseTC transaction management
HubSpothubspotCRM — deal pipeline coordination
InvestorLiftinvestorliftWholesale marketplace
Buyer blast processbuyer-blastBlast deals to buyers after TC open

Open issues / TODOs

  • Webhooks not documented in OTC API — using Zapier integration for event triggers; evaluate if native webhook support added post-2026-03-17
  • OTC api_data field supports Follow Up Boss, Dotloop, Brokermint, SkySlope IDs — HubSpot deal-id association uses custom field approach; document the exact custom property name used
  • Document template IDs for RERI transaction types (GET /v1/propertyTemplates/) — needed for automated property creation
  • Rate limit is strict at 1 req/sec — any bulk operations must implement mandatory 1.1s delay between calls
  • endpoints-parsed.json (91KB) is the machine-readable source for code generation — prefer over API.md for programmatic use

Recent activity

  • 2026-05-03: hub created (W2-S9); sourced from knowledge-base/opentoclose/API.md (verified 2026-03-17 live scrape)