# Hummingbird API # Tenant Inc , Hummingbird PMS , API Spec > Property Management System API for AI Agents > Version: 1.0 | Last Updated: March 27, 2026 > OpenAPI 3.0 Specification ## API Overview This is the Hummingbird Property Management System API designed for AI agents, automation tools, and third-party integrations. The API manages storage facilities, spaces, tenants, leases, payments, rentals and reservations. **Important**: All API endpoints follow this URL structure: `https://prod.edge.tenant.dev/api/v3/applications/{application_id}/v1/{endpoint}` API Specs are defined here : OpenAPI: https://www.tenant.dev/hummingbird.json The `{application_id}` is required in the URL path for all API calls. ## Quick Reference - **API Spec URL**: `/hummingbird.json` (public, no auth required) - **AI Agent Guide**: `/llms.txt` (public, no auth required) - **OpenAPI: https://www.tenant.dev/hummingbird.json - **Format**: OpenAPI 3.0 JSON - **Base URL**: `https://prod.edge.tenant.dev/api/v3/applications/{application_id}/v1/` - **Authentication**: Required for all API calls (API key + timestamp headers) - **Spec Download**: No authentication required - **Cache**: 1-hour cache on spec endpoint ## Entity Model ``` Company (root entity) ├── Properties (storage facilities) │ ├── Units (storage spaces) │ ├── Space Groups (unit categories) │ └── Settings (taxes, rules) ├── Contacts (tenants/customers) │ ├── Leads (prospective tenants) │ ├── Payment Methods │ └── Interactions └── Leases (rental agreements) ├── Invoices ├── Payments └── Insurance ``` ## Required ID Types - `application_id` - Application identifier (required in URL path) - `company_id` - Root identifier (required for all operations) - `property_id` - Facility/location identifier - `unit_id` - Storage space identifier - `contact_id` - Tenant/customer identifier - `lease_id` - Rental agreement identifier - `lead_id` - Prospective tenant identifier ## Authentication Headers All API calls (except spec download) require: ``` X-storageapi-key: {your_api_key} X-storageapi-date: {current_timestamp} X-trace-id: {for tracing the workflow} {optional but recomended} ``` ## API Categories 1. **Contacts** (Tenant Management) - Check/create contacts - Update contact info - Manage addresses, phones, business details - Track interactions 2. **Leads** (Prospective Tenants) - Create and track leads - Track the leads by source, medium and channel - Convert to active tenants - Retire leads 3. **Leases** (Rental Agreements) - Create/update leases - Close leases - View ledger and invoices - Manage insurance 4. **Units** (Storage Spaces) - List available units - Reserve units - Hold units - Bulk price updates 5. **Properties** (Facilities) - List all properties - Get property details - Manage tax rates - Configure space groups 6. **Payments** (Billing & Transactions) - Add payment methods - Process payments - Generate payment links - Enable autopay 7. **Reservations** (Unit Reservations) - Create reservations - View reservation status - Manage settings 8. **Reports** (Business Analytics) - Management summaries - Transfer reports - Rental activity - Occupancy statistics 9. **Promotions** (Discounts & Offers) - Create promotions - List active offers 10. **Rate Management** (Pricing) - Create rate changes - Bulk rate updates 11. **Accounting** (Financial Exports) - Export accounting data 12. **Space Groups** (Unit Categories) - List space groups - Get space types 13. **Tenants** (Active Tenant Queries) - Query all tenants ## Common Workflows for AI Agents ### Workflow 1: New Tenant Onboarding ``` Base: https://prod.edge.tenant.dev/api/v3/applications/{application_id} Step 1: Check if contact exists GET /v1/companies/{company_id}/contacts/check?first={first}&last={last}&email={email} Step 2: Create lead (if new contact) POST /v1/companies/{company_id}/leads/ Step 3: Find available unit GET /v1/companies/{company_id}/properties/{property_id}/units/available?date={move_in_date} Step 4: Create reservation (optional) POST /v1/companies/{company_id}/units/{unit_id}/reserve Step 5: Create lease POST /v1/companies/{company_id}/units/{unit_id}/lease Step 6: Generate move-in invoice POST /v1/companies/{company_id}/leases/{lease_id}/generate-move-in-invoice Step 7: Add payment method POST /v1/companies/{company_id}/payments/payment-method Step 8: Enable autopay (optional) PUT /v1/companies/{company_id}/leases/{lease_id}/payment-methods/{payment_method_id}/autopay ``` ### Workflow 2: Payment Processing ``` Step 1: Get unpaid invoices GET /v1/companies/{company_id}/leases/{lease_id}/invoices Step 2: Get payment methods GET /v1/companies/{company_id}/contacts/{contact_id}/payment-methods Step 3: Process payment Option A: POST /v1/companies/{company_id}/payments/bulk Option B: GET /v1/companies/{company_id}/contacts/{contact_id}/one-time-link (generate payment link) Step 4: Enable autopay (optional) PUT /v1/companies/{company_id}/leases/{lease_id}/payment-methods/{payment_method_id}/autopay ``` ### Workflow 3: Move-Out Process ``` Step 1: Get move-out leases GET /v1/companies/{company_id}/leases/move-out Step 2: Check ledger balance GET /v1/companies/{company_id}/leases/{lease_id}/ledger Step 3: Close lease PUT /v1/companies/{company_id}/leases/{lease_id}/close ``` ### Workflow 4: Property Management ``` Step 1: List all properties GET /v1/companies/{company_id}/properties/ Step 2: Get property details GET /v1/companies/{company_id}/properties/{property_id} Step 3: Get available units GET /v1/companies/{company_id}/properties/{property_id}/units/available Step 4: Get management summary GET /v1/companies/{company_id}/properties/{property_id}/reports/management-summary?date={date} ``` ## Decision Tree: Finding Tenant Information ``` Q: Do you have contact_id? ├─ YES → GET /v1/companies/{company_id}/contacts/{contact_id} └─ NO → Q: Do you have name, email, or phone? ├─ YES → GET /v1/companies/{company_id}/contacts/check?first={first}&last={last}&email={email}&phone={phone} └─ NO → Cannot proceed (need identifier) Q: Need transaction history? └─ GET /v1/companies/{company_id}/contacts/{contact_id}/transactions Q: Need payment methods? └─ GET /v1/companies/{company_id}/contacts/{contact_id}/payment-methods Q: Need active leases? └─ GET /v1/companies/{company_id}/contacts/{contact_id} (includes leases in response) ``` ## Response Format All API responses follow this structure: **Success Response:** ```json { "status": 200, "data": { /* response data */ }, "message": "Success" } ``` **Error Response:** ```json { "status": 400, "data": null, "message": "Error description" } ``` ## Response Codes - `200` - Success - `400` - Bad Request (invalid parameters) - `401` - Unauthorized (check API key/timestamp) - `403` - Forbidden (insufficient permissions) - `404` - Not Found (entity doesn't exist) - `500` - Server Error (retry with backoff) ## Query Parameters | Parameter | Type | Description | Example | |-----------|------|-------------|---------| | offset | integer | Pagination start position | ?offset=0 | | limit | integer | Items per page (default 100) | ?limit=100 | | concise | boolean | Return condensed data | ?concise=true | | status | string | Filter by status | ?status=active | | date | string | Filter by date (YYYY-MM-DD) | ?date=2024-12-31 | | sortKey | string | Field to sort by | ?sortKey=created | | sortOrder | string | asc or desc | ?sortOrder=desc | ## Pagination Strategy for AI Agents ```python offset = 0 limit = 100 all_results = [] while True: response = api_call(offset=offset, limit=limit) results = response['data'] if not results or len(results) == 0: break all_results.extend(results) if len(results) < limit: break # Last page offset += limit ``` ## Error Handling Strategy for AI Agents ```python def make_api_call(endpoint, method, data=None): try: response = http_request(endpoint, method, data) if response.status == 200: return response.data elif response.status == 400: raise ValueError(f"Invalid request: {response.message}") elif response.status == 401: raise AuthenticationError("Check X-storageapi-key and X-storageapi-date") elif response.status == 404: return None # Entity not found elif response.status >= 500: return retry_with_backoff(endpoint, method, data) except Exception as e: log_error(e) raise ``` ## Data Validation Checklist ### Contact Creation/Update - [ ] `first` name provided (required) - [ ] `last` name provided (required) - [ ] `email` in valid format - [ ] `phone` is numeric (10 digits) - [ ] Address: address, city, state, zip ### Lease Creation - [ ] `start_date` in YYYY-MM-DD format (required) - [ ] `contacts` array has ≥1 contact (required) - [ ] `unit_id` exists and available (required) - [ ] `rent` is positive number (required) - [ ] `bill_day` between 1-28 ### Payment Processing - [ ] `lease_id` exists and active - [ ] Payment method exists (for autopay) - [ ] Amount matches invoice ### Unit Availability - [ ] `date` in YYYY-MM-DD format - [ ] `date` not in past - [ ] `property_id` exists ## Performance Optimization for AI Agents 1. **Use concise mode** for lists: `?concise=true` - Reduces response size - Max 1000 items (vs 200 default) 2. **Cache property/unit data** - Changes infrequently - Cache for 1+ hours 3. **Use bulk operations** - Bulk payments: POST /payments/bulk - Bulk price updates: PUT /units/bulk-edit-prices 4. **Appropriate page sizes** - Start with limit=100 - Increase to 1000 for concise mode - `GET /v1/companies/{company_id}/properties/{property_id}/leases` uses default 20 and maximum 500 5. **Parallelize independent reads** - Fetch multiple entities concurrently - Don't wait for sequential responses ## State Management ### Contact States - `active` - Active tenant - `inactive` - Former tenant ### Lease States - `status: 0` - Pending - `status: 1` - Active - `status: 2` - Closed - `auction_status` - In collections ### Unit States - `available_date` - When available - `featured` - Featured listing - Check leases endpoint for occupancy ## Common Patterns ### Pattern 1: Check Before Create ``` 1. Check if entity exists 2. If exists → use existing ID 3. If not → create new entity ``` ### Pattern 2: Get Related Entities ``` 1. GET primary entity 2. Extract related IDs from response 3. Fetch related entities if needed ``` ### Pattern 3: Multi-Step Workflows ``` 1. Validate prerequisites 2. Execute steps in order 3. Verify each step 4. Rollback on failure (where supported) ``` ## Rate Limiting Recommendations 1. **Exponential Backoff** - Initial retry: 1 second - Double delay each retry - Max retries: 3-5 2. **Request Throttling** - Max concurrent: 5 requests - Delay: 100ms between requests 3. **Use Bulk Endpoints** - Reduces total API calls ## Security Best Practices for AI Agents 1. **Never log sensitive data** - Don't log API keys - Redact SSN, payment info 2. **Use HTTPS only** - Verify SSL certificates 3. **Rotate API keys regularly** - Update periodically - Rotate immediately if compromised 4. **Validate all inputs** - Sanitize user data - Prevent injection ## Testing Checklist for AI Agents 1. **Read-Only Test** ``` GET /v1/companies/{company_id}/properties/ Verify: Response matches schema ``` 2. **Entity Existence Test** ``` GET /v1/companies/{company_id}/contacts/check Verify: Can find/create contacts ``` 3. **Workflow Test** ``` Execute: Complete tenant onboarding Verify: All steps succeed ``` 4. **Error Handling Test** ``` Call: Invalid endpoint Verify: Proper error response ``` ## Debugging Checklist When API calls fail, check: - [ ] `company_id` is correct - [ ] Authentication headers present - [ ] Timestamp format correct in `X-storageapi-date` - [ ] API key valid in `X-storageapi-key` - [ ] Request body matches schema - [ ] All required fields included - [ ] Date formats are YYYY-MM-DD - [ ] No typos in parameter names - [ ] IDs exist before using in path - [ ] Review `message` field in response ## Key Endpoints Reference ### Contacts - `GET /v1/companies/{company_id}/contacts/check` - Check existence - `GET /v1/companies/{company_id}/contacts/{contact_id}` - Get details - `PUT /v1/companies/{company_id}/contacts/{contact_id}` - Update - `GET /v1/companies/{company_id}/contacts/{contact_id}/transactions` - Transactions - `GET /v1/companies/{company_id}/contacts/{contact_id}/payment-methods` - Payment methods ### Leads - `GET /v1/companies/{company_id}/leads/` - List leads - `POST /v1/companies/{company_id}/leads/` - Create lead - `GET /v1/companies/{company_id}/leads/{lead_id}` - Get lead - `PUT /v1/companies/{company_id}/leads/{lead_id}/retire` - Retire lead ### Leases - `GET /v1/companies/{company_id}/leases/` - List leases - `GET /v1/companies/{company_id}/properties/{property_id}/leases` - List leases for a property (default limit 20, maximum 500) - `GET /v1/companies/{company_id}/leases/{lease_id}` - Get lease - `DELETE /v1/companies/{company_id}/leases/{lease_id}` - Cancel lease - `PUT /v1/companies/{company_id}/leases/{lease_id}/close` - Close lease - `GET /v1/companies/{company_id}/leases/{lease_id}/ledger` - Ledger - `GET /v1/companies/{company_id}/leases/{lease_id}/invoices` - Invoices ### Units - `GET /v1/companies/{company_id}/properties/{property_id}/units` - List units - `GET /v1/companies/{company_id}/units/{unit_id}` - Unit details - `POST /v1/companies/{company_id}/units/{unit_id}/lease` - Create lease - `POST /v1/companies/{company_id}/units/{unit_id}/reserve` - Reserve unit - `GET /v1/companies/{company_id}/properties/{property_id}/units/available` - Available units ### Properties - `GET /v1/companies/{company_id}/properties/` - List properties - `GET /v1/companies/{company_id}/properties/{property_id}` - Property details - `PUT /v1/companies/{company_id}/properties/{property_id}` - Update property ### Payments - `POST /v1/companies/{company_id}/payments/payment-method` - Add payment method - `POST /v1/companies/{company_id}/payments/bulk` - Bulk payments - `GET /v1/companies/{company_id}/contacts/{contact_id}/one-time-link` - Payment link - `PUT /v1/companies/{company_id}/leases/{lease_id}/payment-methods/{payment_method_id}/autopay` - Enable autopay ### Reports - `GET /v1/companies/{company_id}/reports/management-summary` - Company summary - `GET /v1/companies/{company_id}/properties/{property_id}/reports/management-summary` - Property summary - `GET /v1/companies/{company_id}/reports/rental-activity` - Rental activity - `GET /v1/companies/{company_id}/reports/daily-deposits` - Daily deposits ## Example API Calls ### Check if Contact Exists ```bash curl --location 'https://prod.edge.tenant.dev/api/v3/applications/{application_id}/v1/companies/{company_id}/contacts/check?first=John&last=Doe&email=john@example.com' \ --header 'X-storageapi-key: your_api_key' \ --header 'X-storageapi-date: 2026-03-27T10:00:00Z' ``` ### Create Lease ```bash curl --location 'https://prod.edge.tenant.dev/api/v3/applications/{application_id}/v1/companies/{company_id}/units/{unit_id}/lease' \ --header 'X-storageapi-key: your_api_key' \ --header 'X-storageapi-date: 2026-03-27T10:00:00Z' \ --header 'Content-Type: application/json' \ --data '{ "start_date": "2026-04-01", "contacts": [{"contact_id": "contact789"}], "rent": 150.00, "bill_day": 1 }' ``` ### Get Available Units ```bash curl --location 'https://prod.edge.tenant.dev/api/v3/applications/{application_id}/v1/companies/{company_id}/properties/{property_id}/units/available?date=2026-04-01&status=active' \ --header 'X-storageapi-key: your_api_key' \ --header 'X-storageapi-date: 2026-03-27T10:00:00Z' ``` ## Integration Tips for AI Agents 1. **Always start with spec download** - Parse `/hummingbird.json` - Read `/llms.txt` for AI-specific guidance - Validate your requests against schemas 2. **Follow workflows sequentially** - Don't skip prerequisite steps - Verify each step before proceeding 3. **Handle all error codes** - Implement retry logic for 5xx - Log and report 4xx for debugging 4. **Use transaction logging** - Track all API calls - Log request/response for audit 5. **Implement health checks** - Periodically test connectivity - Verify API key validity ## Support & Resources - **API Specification**: `/hummingbird.json` - **Full Documentation**: `/docs/apis/HUMMINGBIRD_API_GUIDE.md` - **AI Integration Guide**: `/docs/apis/AI_AGENT_GUIDE.md` - **Project README**: `/docs/apis/README.md` ## Version Information - **API Version**: v1 - **OpenAPI Version**: 3.0.0 - **Last Updated**: March 27, 2026 - **Total Endpoints**: 77 - **Categories**: 13 - **Specification Size**: 1.1 MB --- This llms.txt file is designed for AI agent consumption. It provides structured, parseable information about the Hummingbird Property Management API with decision trees, workflows, validation rules, and best practices. For human-readable documentation, see the markdown files in /docs/apis/