Getting Started with the Viv API

Welcome to the Viv Public API. This guide will help you integrate with Viv's home care management platform to access client data, manage caregivers, schedule visits, and more.

Base URL: https://api.vivtechnologies.com/v2


Quick Start

1. Get Your API Key

Contact your Viv account manager or email [email protected] to request API access. You'll receive:

  • API Key — Your unique authentication credential
  • Environment — Production or Sandbox access
  • Geo Access — Which geographic regions you can access

2. Make Your First Request

Test your credentials by fetching the configuration:

curl -X GET "https://api.vivtechnologies.com/v2/config/geos" \
  -H "x-api-key: YOUR_API_KEY"

Response:

{
  "data": [
    {
      "id": "5633a2df99b4cd291e7044d8",
      "name": "Toronto",
      "timezone": "America/Toronto"
    }
  ]
}

If you see your authorized geos, you're ready to go!


Authentication

All API requests require an API key passed in the x-api-key header:

curl -X GET "https://api.vivtechnologies.com/v2/clients" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json"
HeaderRequiredDescription
x-api-keyYesYour API key
Content-TypeYesapplication/json for all requests

Security Note: Keep your API key secure. Never expose it in client-side code, public repositories, or logs. If compromised, contact us immediately for rotation.


Environments

EnvironmentBase URLPurpose
Productionhttps://api.vivtechnologies.com/v2Live data
Sandboxhttps://api-sandbox.vivtechnologies.com/v2Testing & development

Sandbox mirrors production but contains synthetic data. Test all integrations in sandbox before going live.


Core Concepts

Geos (Geographic Regions)

Viv organizes data by geographic region. Your API key grants access to specific geos. All entities (clients, caregivers, visits) belong to a geo.

{
  "geo": {
    "id": "5633a2df99b4cd291e7044d8",
    "name": "Toronto",
    "timezone": "America/Toronto"
  }
}

Attributes

Many fields use configurable attributes that vary by agency. These are returned as {id, text} pairs:

{
  "certifications": [
    { "id": "5633a2df99b4cd291e704530", "text": "PSW" },
    { "id": "5633a2df99b4cd291e704531", "text": "First Aid" }
  ]
}

Fetch available attributes via /config/attributes.

IDs

All entities use MongoDB ObjectIDs (24-character hex strings):

507f1f77bcf86cd799439011

Pagination

List endpoints return paginated results:

GET /v2/clients?limit=20&offset=40
ParameterDefaultMaxDescription
limit20100Results per page
offset0Number of results to skip

Response:

{
  "data": [...],
  "pagination": {
    "total": 1250,
    "limit": 20,
    "offset": 40,
    "hasMore": true
  }
}

Syncing Data

Use updatedSince to fetch only changed records:

GET /v2/clients?updatedSince=2024-12-01T00:00:00Z

This returns all clients created or modified after the specified timestamp. Store the latest updatedAt from your sync and use it for subsequent requests.

Recommended sync pattern:

  1. Initial full sync (paginate through all records)
  2. Store timestamp of sync completion
  3. Subsequent syncs use updatedSince with stored timestamp
  4. Process updates and deletions

Rate Limits

OperationLimit
Read requests (GET)10 requests/second
Write requests (POST/PUT/DELETE)1 request/second

When rate limited, you'll receive:

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests. Please retry after 1 second.",
    "retryAfter": 1
  }
}

Implement exponential backoff for production integrations.


Error Handling

All errors follow a consistent format:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request parameters",
    "details": {
      "field": "email",
      "reason": "Invalid email format"
    }
  }
}

HTTP Status Codes

CodeMeaning
200Success
201Created
204Deleted (no content)
400Bad request / Validation error
401Invalid or missing API key
403Forbidden (insufficient scope or locked resource)
404Resource not found
429Rate limited
500Server error

Common Error Codes

CodeDescription
VALIDATION_ERRORRequest body failed validation
NOT_FOUNDResource doesn't exist
UNAUTHORIZEDAPI key invalid or missing
FORBIDDENAPI key lacks required scope
LOCKEDResource is locked (e.g., visit in finalized payroll)
DUPLICATEResource already exists
RATE_LIMITEDToo many requests

Locked Resources

Certain resources become locked and cannot be modified:

  • Visits locked when included in finalized payroll, submitted for billing, or sent to EVV aggregator
  • EVV Records locked after submission to state aggregator

Attempting to modify a locked resource returns:

{
  "error": {
    "code": "LOCKED",
    "message": "Visit is locked for payroll and cannot be modified",
    "details": {
      "lockReason": "payroll",
      "lockedAt": "2024-12-15T00:00:00Z"
    }
  }
}

Webhooks

Subscribe to real-time events instead of polling:

POST /v2/webhooks
{
  "name": "Client Updates",
  "url": "https://your-app.com/webhooks/viv",
  "events": ["client.created", "client.updated", "visit.completed"]
}

Available events:

  • client.created, client.updated, client.status_changed
  • caregiver.created, caregiver.activated, caregiver.terminated
  • visit.created, visit.completed, visit.cancelled
  • evv.check_in, evv.check_out
  • And many more...

See the Webhooks API for full documentation.


Common Workflows

Sync Clients to External System

import requests
from datetime import datetime

API_KEY = "your_api_key"
BASE_URL = "https://api.vivtechnologies.com/v2"
headers = {"x-api-key": API_KEY}

# Get all clients (initial sync)
def sync_all_clients():
    clients = []
    offset = 0
    while True:
        resp = requests.get(
            f"{BASE_URL}/clients",
            headers=headers,
            params={"limit": 100, "offset": offset}
        )
        data = resp.json()
        clients.extend(data["data"])
        if not data["pagination"]["hasMore"]:
            break
        offset += 100
    return clients

# Incremental sync
def sync_updated_clients(since: str):
    return requests.get(
        f"{BASE_URL}/clients",
        headers=headers,
        params={"updatedSince": since, "limit": 100}
    ).json()

Create a Visit

POST /v2/visits
{
  "clientId": "507f1f77bcf86cd799439011",
  "caregiverId": "507f1f77bcf86cd799439021",
  "scheduledStart": "2024-12-15T09:00:00-05:00",
  "scheduledEnd": "2024-12-15T13:00:00-05:00",
  "bookingTypeId": "5633a2df99b4cd291e704540",
  "notes": "Client prefers caregiver to enter through side door"
}

SDKs & Tools

ResourceLink
OpenAPI SpecDownload YAML
Postman CollectionImport to Postman
Python SDKComing soon
Node.js SDKComing soon

Support

ChannelContact
Technical Support[email protected]
Account ManagementYour dedicated account manager
Status Pagestatus.vivtechnologies.com

Response Times:

  • Critical issues: 4 hours
  • General inquiries: 1 business day

What's Next?

  1. API Reference — Explore all endpoints
  2. Clients API — Manage client records
  3. Visits API — Schedule and track visits
  4. Webhooks — Set up real-time notifications