The Volunteer API has a single documented base URL. This page covers the URL structure, the /v1/ versioning convention, the HTTPS requirements, and what’s known about test or sandbox environments.
The single documented base URL
That’s the entire spec-documented surface. Every endpoint in the API is reached by appending the endpoint path to this base — GET /v1/users is GET https://api.vomo.org/v1/users.
| Component | Value |
|---|
| Protocol | https only — plain HTTP is not supported |
| Host | api.vomo.org |
| Version segment | /v1 — present on every path |
| Resource paths | /users, /projects, /groups, /campaigns, /organizations, /forms, /certificates |
A few example requests showing the full URL structure:
GET https://api.vomo.org/v1/users
GET https://api.vomo.org/v1/users/12345
GET https://api.vomo.org/v1/projects?page=2
POST https://api.vomo.org/v1/groups
GET https://api.vomo.org/v1/forms/789/completions
The version segment (/v1) is part of the base URL — not part of individual endpoint paths. When the documentation refers to an endpoint as GET /users, the full URL is https://api.vomo.org/v1/users.
The /v1 versioning convention
Volunteer’s base URL includes an explicit /v1 segment. This is different from the other two Virtuous APIs:
| API | Base URL | Version segment? |
|---|
| CRM+ | https://api.virtuoussoftware.com/api | No |
| Raise | https://prod-api.raisedonors.com/api | No |
| Volunteer | https://api.vomo.org/v1 | Yes |
What this means for partner integrations
The presence of /v1 suggests the platform may introduce future versions (/v2, etc.) without breaking existing integrations. Integrations targeting /v1 should continue to work as long as the v1 contract is maintained, even after a v2 is released.
This is purely speculative for now — no v2 exists. But the URL pattern is set up for a future migration to be possible.
For practical integration code, hardcode the /v1 in your base URL constant:
const VOMO_BASE_URL = 'https://api.vomo.org/v1';
async function get(path, options = {}) {
return fetch(`${VOMO_BASE_URL}${path}`, options);
}
// Usage
const users = await get('/users');
const oneUser = await get('/users/12345');
If a v2 is released someday, switching is a one-line change to the constant — assuming the path structure is preserved.
See Versioning and Backward Compatibility for the broader discussion.
HTTPS is required
All Volunteer API requests must use HTTPS. The platform does not respond to plain HTTP requests, and any code that attempts http://api.vomo.org/v1/users will fail or be redirected.
| Why HTTPS matters |
|---|
The Bearer token in the Authorization header would be visible on the wire over plain HTTP |
| PII in responses (names, emails, addresses) would be visible over plain HTTP |
| Modern browsers and many HTTP clients block or warn on plain-HTTP API calls |
| Compliance frameworks (PCI, SOC 2, GDPR) require encryption in transit |
In practice, this means every integration uses https:// in its URL constant. Don’t try to override certificate validation, use self-signed certs against the production host, or otherwise loosen the TLS posture.
TLS version
The Volunteer API requires TLS 1.2 or later. Most modern HTTP libraries default to this, but legacy clients (very old Java, old PHP, certain embedded systems) may need explicit configuration.
If you see TLS handshake errors, check the client’s TLS configuration before suspecting the API.
Test and sandbox environments
The Volunteer OpenAPI spec documents one host: production. There’s no separately-documented sandbox URL.
⚠️ Spec gap: The OpenAPI spec doesn’t expose a sandbox or test environment. Test and development access is typically handled by issuing a token against a dedicated test organization on the production host, rather than by using a separate URL. Coordinate with the customer’s VOMO concierge if a dedicated test environment is needed.
What this means in practice
For partner integration development:
| Approach | When to use |
|---|
| Develop against a customer’s test organization | If the customer has a separate VOMO organization specifically for testing, use a token from that organization. |
| Develop against a developer-owned VOMO account | The partner sets up their own VOMO account specifically for integration development. |
| Develop against production with care | Last resort — only if no test organization is available. Use clearly-marked test data (dev+timestamp@example.com emails). |
The production host is https://api.vomo.org/v1 regardless of which approach you use. Isolation is at the organization (token) level, not the URL level.
Don’t develop against a real customer’s production data
A common anti-pattern: developing the integration against a real customer’s live VOMO account. This produces test users mingled with real users, test groups in production reports, and potentially destructive operations affecting real records.
The right path is to coordinate a test organization upfront. If the customer doesn’t have one, request that one be set up before integration development begins.
Service health and status
The Volunteer OpenAPI spec doesn’t document a status page URL or health-check endpoint.
For partner integrations operating at scale, knowing when the API is degraded matters — sustained 5xx responses or elevated latency may indicate a platform issue rather than an integration bug.
What partner integrations can do
| Practice | Description |
|---|
| Track 5xx response rate | A spike across multiple customers usually means a platform issue, not a per-customer one. |
| Track API latency over time | Sudden latency increases without your traffic changing typically indicate platform-side issues. |
| Maintain a status page for the integration | Independent of VOMO — communicates to your customers when your integration is degraded for any reason. |
| Coordinate with VOMO during incidents | When sustained issues appear, reach out to VOMO support to confirm whether it’s a platform issue. |
Don’t poll the API to detect health — that wastes rate-limit budget. Track the health of real workloads instead.
Latency and geographic considerations
The spec doesn’t document the API’s deployment geography or expected latency from different regions. In practice, partner integrations should expect:
| Source region | Expected latency to API |
|---|
| North America | Low (typically <100ms for a simple GET) |
| Europe | Moderate (typically <200ms) |
| Asia / Pacific | Higher (varies; can be >300ms) |
These are typical web API characteristics, not specific guarantees. For latency-sensitive workloads, measure from your actual deployment environment.
Implications for sync architecture
For integrations doing bulk reads (backfills, daily reconciliation), latency adds up. A backfill of 100,000 users with 100ms round-trip per request takes ~3 hours even with no rate-limit throttling. Plan for this when scoping the backfill window.
The patterns on Sync Architecture Patterns cover backfill design for large datasets.
URL construction patterns
A few practices that prevent common URL-construction bugs:
Don’t hand-concatenate query parameters
// ❌ Anti-pattern — breaks on special characters
const url = `https://api.vomo.org/v1/users?name_like=${searchTerm}`;
// ✅ Use URLSearchParams (or equivalent)
const params = new URLSearchParams({ name_like: searchTerm });
const url = `https://api.vomo.org/v1/users?${params}`;
Names with spaces, apostrophes, or other characters need URL encoding. Manual concatenation forgets this; URLSearchParams handles it correctly.
Don’t hand-construct paginated URLs
// ❌ Anti-pattern — breaks if pagination changes
const nextUrl = `${baseUrl}/users?page=${currentPage + 1}`;
// ✅ Follow links.next from the previous response
const nextUrl = previousResponse.links.next;
The API tells you the next page’s URL in links.next. Use it. Manual page-number construction works today but can break if the pagination scheme evolves.
Don’t strip /v1/ from URLs returned by the API
The links field in paginated responses includes the full URL with /v1/:
{
"links": {
"next": "https://api.vomo.org/v1/users?page=2"
}
}
If your code strips the version segment (“I’ll add it myself when I make the call”), you’ll either double-prefix or miss it entirely. Use returned URLs as-is.
Be cautious with trailing slashes
The Volunteer paths don’t include trailing slashes in the spec:
✅ /users
✅ /users/12345
❌ /users/ (trailing slash — typically rejected or redirected)
Most HTTP clients handle this correctly, but if you’re constructing URLs by string template, double-check that you’re not appending a stray /.
A reference base URL setup
A minimal, well-organized base URL setup for a partner integration:
// config.js
export const VOMO_API_BASE_URL = 'https://api.vomo.org/v1';
// vomo-client.js
import { VOMO_API_BASE_URL } from './config.js';
export class VomoClient {
constructor({ token }) {
this.token = token;
}
async _request(path, options = {}) {
const url = path.startsWith('http') ? path : `${VOMO_API_BASE_URL}${path}`;
const response = await fetch(url, {
...options,
headers: {
Authorization: `Bearer ${this.token}`,
Accept: 'application/json',
...options.headers,
},
});
if (!response.ok) {
throw await this._buildError(response);
}
return response.json();
}
async getUsers(params = {}) {
const query = new URLSearchParams(params).toString();
return this._request(`/users${query ? `?${query}` : ''}`);
}
async getUser(userId) {
return this._request(`/users/${userId}`);
}
async followLink(url) {
// For pagination — accept the full URL from a previous response
return this._request(url);
}
}
This pattern:
- Defines the base URL in one place (easy to change for future v2).
- Auto-detects whether a path or full URL is passed (so
followLink works with links.next).
- Centralizes auth headers (no per-call boilerplate).
- Throws structured errors (caller doesn’t deal with raw
Response objects).
Where to go next
Walk through a slightly richer call now that the URL structure is clear.The Bearer token pattern used with this base URL.How the links.next URLs returned by the API work.The longer discussion of /v1 and what a future /v2 might mean.
The Volunteer API has a single documented base URL. This page covers the URL structure, the /v1/ versioning convention, the HTTPS requirements, and what’s known about test or sandbox environments.
The single documented base URL
That’s the entire spec-documented surface. Every endpoint in the API is reached by appending the endpoint path to this base — GET /v1/users is GET https://api.vomo.org/v1/users.
| Component | Value |
|---|
| Protocol | https only — plain HTTP is not supported |
| Host | api.vomo.org |
| Version segment | /v1 — present on every path |
| Resource paths | /users, /projects, /groups, /campaigns, /organizations, /forms, /certificates |
A few example requests showing the full URL structure:
GET https://api.vomo.org/v1/users
GET https://api.vomo.org/v1/users/12345
GET https://api.vomo.org/v1/projects?page=2
POST https://api.vomo.org/v1/groups
GET https://api.vomo.org/v1/forms/789/completions
The version segment (/v1) is part of the base URL — not part of individual endpoint paths. When the documentation refers to an endpoint as GET /users, the full URL is https://api.vomo.org/v1/users.
The /v1 versioning convention
Volunteer’s base URL includes an explicit /v1 segment. This is different from the other two Virtuous APIs:
| API | Base URL | Version segment? |
|---|
| CRM+ | https://api.virtuoussoftware.com/api | No |
| Raise | https://prod-api.raisedonors.com/api | No |
| Volunteer | https://api.vomo.org/v1 | Yes |
What this means for partner integrations
The presence of /v1 suggests the platform may introduce future versions (/v2, etc.) without breaking existing integrations. Integrations targeting /v1 should continue to work as long as the v1 contract is maintained, even after a v2 is released.
This is purely speculative for now — no v2 exists. But the URL pattern is set up for a future migration to be possible.
For practical integration code, hardcode the /v1 in your base URL constant:
const VOMO_BASE_URL = 'https://api.vomo.org/v1';
async function get(path, options = {}) {
return fetch(`${VOMO_BASE_URL}${path}`, options);
}
// Usage
const users = await get('/users');
const oneUser = await get('/users/12345');
If a v2 is released someday, switching is a one-line change to the constant — assuming the path structure is preserved.
See Versioning and Backward Compatibility for the broader discussion.
HTTPS is required
All Volunteer API requests must use HTTPS. The platform does not respond to plain HTTP requests, and any code that attempts http://api.vomo.org/v1/users will fail or be redirected.
| Why HTTPS matters |
|---|
The Bearer token in the Authorization header would be visible on the wire over plain HTTP |
| PII in responses (names, emails, addresses) would be visible over plain HTTP |
| Modern browsers and many HTTP clients block or warn on plain-HTTP API calls |
| Compliance frameworks (PCI, SOC 2, GDPR) require encryption in transit |
In practice, this means every integration uses https:// in its URL constant. Don’t try to override certificate validation, use self-signed certs against the production host, or otherwise loosen the TLS posture.
TLS version
The Volunteer API requires TLS 1.2 or later. Most modern HTTP libraries default to this, but legacy clients (very old Java, old PHP, certain embedded systems) may need explicit configuration.
If you see TLS handshake errors, check the client’s TLS configuration before suspecting the API.
Test and sandbox environments
The Volunteer OpenAPI spec documents one host: production. There’s no separately-documented sandbox URL.
⚠️ Spec gap: The OpenAPI spec doesn’t expose a sandbox or test environment. Test and development access is typically handled by issuing a token against a dedicated test organization on the production host, rather than by using a separate URL. Coordinate with the customer’s VOMO concierge if a dedicated test environment is needed.
What this means in practice
For partner integration development:
| Approach | When to use |
|---|
| Develop against a customer’s test organization | If the customer has a separate VOMO organization specifically for testing, use a token from that organization. |
| Develop against a developer-owned VOMO account | The partner sets up their own VOMO account specifically for integration development. |
| Develop against production with care | Last resort — only if no test organization is available. Use clearly-marked test data (dev+timestamp@example.com emails). |
The production host is https://api.vomo.org/v1 regardless of which approach you use. Isolation is at the organization (token) level, not the URL level.
Don’t develop against a real customer’s production data
A common anti-pattern: developing the integration against a real customer’s live VOMO account. This produces test users mingled with real users, test groups in production reports, and potentially destructive operations affecting real records.
The right path is to coordinate a test organization upfront. If the customer doesn’t have one, request that one be set up before integration development begins.
Service health and status
The Volunteer OpenAPI spec doesn’t document a status page URL or health-check endpoint.
For partner integrations operating at scale, knowing when the API is degraded matters — sustained 5xx responses or elevated latency may indicate a platform issue rather than an integration bug.
What partner integrations can do
| Practice | Description |
|---|
| Track 5xx response rate | A spike across multiple customers usually means a platform issue, not a per-customer one. |
| Track API latency over time | Sudden latency increases without your traffic changing typically indicate platform-side issues. |
| Maintain a status page for the integration | Independent of VOMO — communicates to your customers when your integration is degraded for any reason. |
| Coordinate with VOMO during incidents | When sustained issues appear, reach out to VOMO support to confirm whether it’s a platform issue. |
Don’t poll the API to detect health — that wastes rate-limit budget. Track the health of real workloads instead.
Latency and geographic considerations
The spec doesn’t document the API’s deployment geography or expected latency from different regions. In practice, partner integrations should expect:
| Source region | Expected latency to API |
|---|
| North America | Low (typically <100ms for a simple GET) |
| Europe | Moderate (typically <200ms) |
| Asia / Pacific | Higher (varies; can be >300ms) |
These are typical web API characteristics, not specific guarantees. For latency-sensitive workloads, measure from your actual deployment environment.
Implications for sync architecture
For integrations doing bulk reads (backfills, daily reconciliation), latency adds up. A backfill of 100,000 users with 100ms round-trip per request takes ~3 hours even with no rate-limit throttling. Plan for this when scoping the backfill window.
The patterns on Sync Architecture Patterns cover backfill design for large datasets.
URL construction patterns
A few practices that prevent common URL-construction bugs:
Don’t hand-concatenate query parameters
// ❌ Anti-pattern — breaks on special characters
const url = `https://api.vomo.org/v1/users?name_like=${searchTerm}`;
// ✅ Use URLSearchParams (or equivalent)
const params = new URLSearchParams({ name_like: searchTerm });
const url = `https://api.vomo.org/v1/users?${params}`;
Names with spaces, apostrophes, or other characters need URL encoding. Manual concatenation forgets this; URLSearchParams handles it correctly.
Don’t hand-construct paginated URLs
// ❌ Anti-pattern — breaks if pagination changes
const nextUrl = `${baseUrl}/users?page=${currentPage + 1}`;
// ✅ Follow links.next from the previous response
const nextUrl = previousResponse.links.next;
The API tells you the next page’s URL in links.next. Use it. Manual page-number construction works today but can break if the pagination scheme evolves.
Don’t strip /v1/ from URLs returned by the API
The links field in paginated responses includes the full URL with /v1/:
{
"links": {
"next": "https://api.vomo.org/v1/users?page=2"
}
}
If your code strips the version segment (“I’ll add it myself when I make the call”), you’ll either double-prefix or miss it entirely. Use returned URLs as-is.
Be cautious with trailing slashes
The Volunteer paths don’t include trailing slashes in the spec:
✅ /users
✅ /users/12345
❌ /users/ (trailing slash — typically rejected or redirected)
Most HTTP clients handle this correctly, but if you’re constructing URLs by string template, double-check that you’re not appending a stray /.
A reference base URL setup
A minimal, well-organized base URL setup for a partner integration:
// config.js
export const VOMO_API_BASE_URL = 'https://api.vomo.org/v1';
// vomo-client.js
import { VOMO_API_BASE_URL } from './config.js';
export class VomoClient {
constructor({ token }) {
this.token = token;
}
async _request(path, options = {}) {
const url = path.startsWith('http') ? path : `${VOMO_API_BASE_URL}${path}`;
const response = await fetch(url, {
...options,
headers: {
Authorization: `Bearer ${this.token}`,
Accept: 'application/json',
...options.headers,
},
});
if (!response.ok) {
throw await this._buildError(response);
}
return response.json();
}
async getUsers(params = {}) {
const query = new URLSearchParams(params).toString();
return this._request(`/users${query ? `?${query}` : ''}`);
}
async getUser(userId) {
return this._request(`/users/${userId}`);
}
async followLink(url) {
// For pagination — accept the full URL from a previous response
return this._request(url);
}
}
This pattern:
- Defines the base URL in one place (easy to change for future v2).
- Auto-detects whether a path or full URL is passed (so
followLink works with links.next).
- Centralizes auth headers (no per-call boilerplate).
- Throws structured errors (caller doesn’t deal with raw
Response objects).
Where to go next
Walk through a slightly richer call now that the URL structure is clear.The Bearer token pattern used with this base URL.How the links.next URLs returned by the API work.The longer discussion of /v1 and what a future /v2 might mean. Last modified on May 22, 2026