Download OpenAPI JSON

Base Public API (1.0)

Download OpenAPI specification:

Base Public API v1

The Base Public API lets you integrate your CRM, advocacy programs and content workflows with the Base platform. All endpoints in this document are part of the stable v1 contract.

Authentication

All requests require a bearer token in the Authorization header:

Authorization: Bearer <your_jwt_token>

Tokens are issued from your company's admin console under Settings → API tokens. Ask your account administrator if you do not have one. Tokens carry the set of authorities (api.user.list, api.points.add, etc.) granted to the issuing user — if a request returns 403, the token is missing the authority the endpoint requires.

Conventions

  • Base URL depends on environment: https://stage.customershome.com/acauth for staging, https://prod.customershome.com/acauth for production.
  • Date/time values are ISO-8601 in UTC (2026-05-12T08:30:00Z).
  • UUIDs are 36-character canonical (550e8400-e29b-41d4-a716-446655440000).
  • Pagination uses Spring-style query parameters: page (0-indexed), size, and sort. Maximum size is 500 unless the endpoint says otherwise.
  • Bulk endpoints process each item independently and report per-item results; a single failed item does not roll back successful ones.
  • Versioning is URL-prefix-based. /api/v1 is the current stable contract. Breaking changes ship as /api/v2 rather than mutating /api/v1 in place; v1 endpoints are supported for at least 12 months after a v2 successor lands.

Rate limits

v1 endpoints are not currently rate-limited at the API edge, but please call considerately:

  • Prefer bulk endpoints (*/bulk, /users-by-dates, */batch) over loops on the single-item variant.
  • Use sinceLastModified for incremental sync rather than re-fetching the full dataset on every poll.
  • Backoff exponentially on 5xx responses and respect Retry-After if present on a future 429 response.

Sustained traffic above ~10 requests/second per token may be subject to throttling in a future release. Subscribe to release notes for the announcement.

Idempotency

  • GET / DELETE / PUT operations are idempotent by definition — replaying the same request never produces a different result.
  • POST create endpoints do not currently support an Idempotency-Key header. Retries after a network failure may create duplicate records; design retries around your own deduplication key (e.g. external CRM contact id).
  • Bulk endpoints commit each item independently, so a retry of the same bulk payload will surface each duplicate item as a per-row error rather than failing the entire batch.

Errors

The API uses standard HTTP status codes. Non-2xx responses carry a JSON body with the shape:

{ "title": "Bad Request", "status": 400, "detail": "Page size must be less than 500" }

Common codes:

Status Meaning
200 Success with a JSON body
201 Created — typically returned by POST endpoints with the new resource's UUID
204 Success with no body — typically returned by DELETE and idempotent operations
400 The request body or parameters failed validation
401 Missing or invalid bearer token
403 The token does not carry the required authority for this endpoint
404 The target resource does not exist
409 Conflict (most often a duplicate name on create/update)
500 Internal error — safe to retry with exponential backoff

Common workflows

CRM → Base sync. Use Import contacts by email (or by-contact-id) to push advocates in bulk, then Modify advocate custom attributes (bulk variant) to push custom-field values. For accounts and opportunities, the Update account data and Upsert opportunity attributes endpoints perform create-or-update in one call.

Activity tracking. Call Trigger activity whenever an advocate completes a tracked event (closed a deal, posted a review, attended a webinar). The activity type configuration in admin determines points awarded and ASK progression.

Leaderboard widget. Call Get leaderboard for the global ranking; call Get leaderboard entry by email to render the current advocate's row inline. Both are cheap to call on page load.

Discovery before write. List endpoints (List custom attributes, List custom object mappings, List activity types) tell you the valid keys and types for the corresponding write endpoints. Cache the result client-side — schemas change rarely.

Terminology

For historical reasons, some resource names in the API differ from their UI labels. See the per-endpoint descriptions for context; the most important mappings are:

  • challenge in the API = ASK in the UI
  • evidence in the API = content in the UI
  • contact (in entity parameters) = advocate record

Advocate Custom Object Records

Bulk create, update, and delete custom object records on advocates.

Modify advocate custom object attributes

Update existing custom object records on advocates. Each batch item identifies the record by its instance ID (returned from a prior create) and supplies the attribute values to change. Items are processed independently — inspect per-record results in the response.

Use this for incremental sync of fields that change over time (e.g. subscription tier, renewal date).

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/advocate/custom-object-record/batch' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "users": [
      {
        "advocateEmail": "ada@example.com",
        "objects": [
          {
            "objectName": "subscription",
            "recordId": "sub-2026-001",
            "attributes": [
              { "attributeName": "plan", "values": ["Enterprise Plus"] }
            ]
          }
        ]
      }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
required
Array of objects (AdvocateAttributesAndRecordsDTO) non-empty

Responses

Request samples

Content type
application/json
{
  • "users": [
    ]
}

Set advocate custom object attributes

Create one or more custom object records (and their attribute values) on advocates. Each item in the batch identifies a target advocate (by UUID or email) and a custom object apiName, then provides the attribute values to set.

Items are processed independently; per-record results — success UUID or error context — are returned in the response body. Use this for bulk-loading multi-row data like subscription history or meeting notes from your CRM.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/advocate/custom-object-record/batch' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "users": [
      {
        "advocateEmail": "ada@example.com",
        "objects": [
          {
            "objectName": "subscription",
            "recordId": "sub-2026-001",
            "attributes": [
              { "attributeName": "plan", "values": ["Enterprise"] },
              { "attributeName": "started_at", "values": ["2026-01-01"] }
            ]
          }
        ]
      }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
required
Array of objects (AdvocateAttributesAndRecordsDTO) non-empty

Responses

Request samples

Content type
application/json
{
  • "users": [
    ]
}

Delete advocate custom object attributes

Delete custom object records on advocates. Each batch item identifies the target advocate (advocateUuid or advocateEmail), the custom object (objectName), and a list of record ids (recordIds) to delete. Passing an empty recordIds array deletes every record of that object type on the advocate. Items are processed independently — per-record outcomes are returned.

Irreversible — the deleted records cannot be recovered.

Example:

curl -X DELETE 'https://prod.customershome.com/acauth/api/v1/advocate/custom-object-record/batch' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "users": [
      {
        "advocateEmail": "ada@example.com",
        "objectName":    "subscription",
        "recordIds":     ["sub-2026-001"]
      }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
required
Array of objects (DeleteAdvocateRecordsDTO) non-empty

Responses

Request samples

Content type
application/json
{
  • "users": [
    ]
}

Account Custom Object Records

Read, create, update and delete custom object records on accounts.

Modify account custom object attributes

Update existing custom object records on accounts. Each batch item identifies the record by its instance ID (returned from a prior create) and supplies the attribute values to change. Items are processed independently — inspect per-record results in the response.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/account/custom-object-record/batch' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "accounts": [
      {
        "accountName": "Analytical Engines Inc.",
        "objects": [
          {
            "objectName": "primary_contact",
            "recordId": "ext-pc-001",
            "attributes": [
              { "attributeName": "email", "values": ["ada.lovelace@example.com"] }
            ]
          }
        ]
      }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
required
Array of objects (AccountAttributesAndRecordsDTO) non-empty

Responses

Request samples

Content type
application/json
{
  • "accounts": [
    ]
}

Set account custom object attributes

Create one or more custom object records (and their attribute values) on accounts. Each batch item identifies a target account (by UUID or name) and a custom object apiName, then provides the attribute values to set.

Items are processed independently — inspect per-record results in the response body.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/account/custom-object-record/batch' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "accounts": [
      {
        "accountName": "Analytical Engines Inc.",
        "objects": [
          {
            "objectName": "primary_contact",
            "recordId": "ext-pc-001",
            "attributes": [
              { "attributeName": "full_name", "values": ["Ada Lovelace"] },
              { "attributeName": "email", "values": ["ada@example.com"] }
            ]
          }
        ]
      }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
required
Array of objects (AccountAttributesAndRecordsDTO) non-empty

Responses

Request samples

Content type
application/json
{
  • "accounts": [
    ]
}

Delete account custom object attributes

Delete custom object records on accounts. Each batch item identifies the target account (accountUuid or accountName), the custom object (objectName), and a list of record ids (recordIds) to delete. Passing an empty recordIds array deletes every record of that object type on the account. Items are processed independently — per-record outcomes are returned.

Irreversible — the deleted records cannot be recovered.

Example:

curl -X DELETE 'https://prod.customershome.com/acauth/api/v1/account/custom-object-record/batch' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "accounts": [
      {
        "accountName": "Analytical Engines Inc.",
        "objectName":  "primary_contact",
        "recordIds":   ["ext-pc-001"]
      }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
required
Array of objects (DeleteAccountRecordsDTO) non-empty

Responses

Request samples

Content type
application/json
{
  • "accounts": [
    ]
}

Get account custom object attribute values

Read custom object records and their attribute values for one account. Identify the account by UUID or name (one of the two is required); identify the custom object by objectName (its apiName from the mapping).

Without instanceId, returns every record of that object type attached to the account. With instanceId, narrows the response to a single record. A common flow is: call the listing endpoint to discover instance IDs, then call this endpoint with one to read a specific record's attributes.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/account/custom-object-record/primary_contact?accountName=Analytical%20Engines%20Inc.' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
path Parameters
objectName
required
string

API name of the custom object

query Parameters
accountUuid
string

UUID of the target account (either accountUuid or accountName is required)

accountName
string

Name of the target account (either accountUuid or accountName is required)

instanceId
string

Optional instance ID to narrow to a specific custom object record

Responses

Custom Attributes

Define and manage custom data attributes on platform entities. Allowed entity values: contact (advocate record), account, opportunity, nomination.

Update custom attribute (full)

Update a custom attribute. Both PUT and PATCH on this endpoint accept the same PatchCustomDataAttributeApiDTO body, and in both cases fields omitted (or sent as null) are left unchanged (booleans are boxed, so null does NOT mean false).

The two verbs differ only in the authority they require: PUT needs api.custom_attribute.add (the same scope used for Create), PATCH needs api.custom_attribute.update. New integrations should prefer PATCH so the token scope is narrow.

The attribute name, type, and owning entity cannot be changed once created — recreate the attribute under a new name if a different type is required.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/custom-attributes/550e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "label": "Favorite color",
    "description": "Updated description",
    "values": ["red", "green", "blue", "yellow"],
    "editableByAdvocate": true,
    "mandatory": false
  }'
Authorizations:
bearer-jwt
path Parameters
uuid
required
string

UUID of the attribute to update

Request Body schema: application/json
required
label
string

New human-readable label

description
string

New description

values
Array of strings unique

New list of allowed values for picklist-style attributes

editableByAdvocate
boolean

Whether the advocate can edit this attribute themselves

mandatory
boolean

Whether a value for this attribute is required

onActivation
boolean

Show in activation flow

showInSourcing
boolean

Show in sourcing flows

showInReport
boolean

Show in admin reports

multipleValues
boolean

Whether the attribute can hold multiple values

showInJoinReferencePoolChallenge
boolean

Show in the Join Reference Pool ASK form

showInReferenceRequestDialog
boolean

Show in the reference request dialog

showInMarketingRequestDialog
boolean

Show in the marketing request dialog

requiredInNominationDialog
boolean

Required when nominating an advocate

Responses

Request samples

Content type
application/json
{
  • "label": "Favorite color",
  • "description": "Updated description",
  • "values": [
    ],
  • "editableByAdvocate": true,
  • "mandatory": true,
  • "onActivation": true,
  • "showInSourcing": true,
  • "showInReport": true,
  • "multipleValues": true,
  • "showInJoinReferencePoolChallenge": true,
  • "showInReferenceRequestDialog": true,
  • "showInMarketingRequestDialog": true,
  • "requiredInNominationDialog": true
}

Delete custom attribute

Delete a custom attribute by UUID. The attribute is removed from every record that had a value for it; existing record values for this attribute are also deleted and cannot be recovered.

Returns 204 No Content on success. Use with care — there is no soft-delete.

Example:

curl -X DELETE 'https://prod.customershome.com/acauth/api/v1/custom-attributes/550e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
path Parameters
uuid
required
string

UUID of the attribute to delete

Responses

Patch custom attribute

Partially update a custom attribute. Only fields present in the request are changed; omitted fields keep their current value (boolean toggles use Boolean so null means "leave unchanged", not "set to false").

Use this endpoint for everyday tweaks (label change, adding allowed picklist values, toggling visibility flags). The attribute name, type, and owning entity remain immutable.

Example:

curl -X PATCH 'https://prod.customershome.com/acauth/api/v1/custom-attributes/550e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{ "label": "Favourite colour" }'
Authorizations:
bearer-jwt
path Parameters
uuid
required
string

UUID of the attribute to patch

Request Body schema: application/json
required
label
string

New human-readable label

description
string

New description

values
Array of strings unique

New list of allowed values for picklist-style attributes

editableByAdvocate
boolean

Whether the advocate can edit this attribute themselves

mandatory
boolean

Whether a value for this attribute is required

onActivation
boolean

Show in activation flow

showInSourcing
boolean

Show in sourcing flows

showInReport
boolean

Show in admin reports

multipleValues
boolean

Whether the attribute can hold multiple values

showInJoinReferencePoolChallenge
boolean

Show in the Join Reference Pool ASK form

showInReferenceRequestDialog
boolean

Show in the reference request dialog

showInMarketingRequestDialog
boolean

Show in the marketing request dialog

requiredInNominationDialog
boolean

Required when nominating an advocate

Responses

Request samples

Content type
application/json
{
  • "label": "Favorite color",
  • "description": "Updated description",
  • "values": [
    ],
  • "editableByAdvocate": true,
  • "mandatory": true,
  • "onActivation": true,
  • "showInSourcing": true,
  • "showInReport": true,
  • "multipleValues": true,
  • "showInJoinReferencePoolChallenge": true,
  • "showInReferenceRequestDialog": true,
  • "showInMarketingRequestDialog": true,
  • "requiredInNominationDialog": true
}

List custom attributes

List custom attributes defined for a given entity (contact = advocate, account, opportunity, nomination).

By default the response includes attributes inherited from a connected CRM in addition to Base-native attributes; pass includeCRM=false to see only the attributes you defined in Base. Use this to discover the schema before reading or writing attribute values on a specific record.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/custom-attributes?entity=contact&includeCRM=true' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
entity
required
string

Entity name whose attributes to list. Accepted values: contact (advocate record), account, opportunity, nomination.

includeCRM
boolean
Default: true

Include attributes inherited from a connected CRM (default true)

Responses

Create custom attribute

Define a new custom attribute on an entity. The name becomes the API key used in all subsequent reads and writes — it must be unique per entity, all-lowercase, and only contain letters / digits / underscores. label is what admins and advocates see in the UI; you can change it later via PATCH.

For picklist attributes set type: "Enumerated" and supply the allowed values up front. To allow selecting multiple values from that list, also set multipleValues: true. For booleans use type: "Boolean" and leave values empty.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/custom-attributes' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "favorite_color",
    "label": "Favorite color",
    "description": "Advocate favorite color",
    "type": "Enumerated",
    "entity": "contact",
    "values": ["red", "green", "blue"],
    "editableByAdvocate": true
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
name
required
string [ 1 .. 64 ] characters ^(?!.*\s)[a-z0-9_]+$

Internal API name. 1 to 64 characters, lowercase letters/digits/underscores only.

label
required
string

Human-readable label shown in UI

description
string

Optional description

type
required
string
Enum: "String" "Integer" "Float" "Boolean" "Date" "Enumerated"

Attribute type

entity
required
string

Entity to attach this attribute to. Accepted values: contact (advocate record), account, opportunity, nomination.

values
Array of strings unique

Allowed values for picklist-style attribute types

editableByAdvocate
boolean

Whether the advocate can edit this attribute themselves

mandatory
boolean

Whether a value for this attribute is required

onActivation
boolean

Show in activation flow

showInSourcing
boolean

Show in sourcing flows

showInReport
boolean

Show in admin reports

multipleValues
boolean

Whether the attribute can hold multiple values

showInJoinReferencePoolChallenge
boolean

Show in the Join Reference Pool ASK form

showInReferenceRequestDialog
boolean

Show in the reference request dialog

showInMarketingRequestDialog
boolean

Show in the marketing request dialog

requiredInNominationDialog
boolean

Required when nominating an advocate

Responses

Request samples

Content type
application/json
{
  • "name": "favorite_color",
  • "label": "Favorite color",
  • "description": "Advocate's favorite color",
  • "type": "String",
  • "entity": "contact",
  • "values": [
    ],
  • "editableByAdvocate": false,
  • "mandatory": false,
  • "onActivation": false,
  • "showInSourcing": false,
  • "showInReport": false,
  • "multipleValues": false,
  • "showInJoinReferencePoolChallenge": false,
  • "showInReferenceRequestDialog": false,
  • "showInMarketingRequestDialog": false,
  • "requiredInNominationDialog": false
}

Nomination

Retrieve reports about advocate nominations.

Get nomination report

Retrieve nomination records that match the provided filter. Nominations are advocate-marketing requests created by salespeople or marketing — typically asking an advocate to participate in a case study, reference call, review, etc.

The filter requires a date range (dateFrom/dateTo) and accepts optional statuses, marketing admin UUIDs, salesperson names, specific nomination UUIDs, activity type names, and a free-text search. Set includeRepeatedNominations=true to surface advocates who were nominated more than once in the window. Use this for reporting / analytics dashboards.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/nomination' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "dateFrom": "2026-01-01",
    "dateTo": "2026-03-31",
    "statuses": ["IN_PROGRESS", "APPROVED"],
    "includeRepeatedNominations": false
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
dateFrom
required
string <date>

Earliest creation date to include (ISO 8601 date)

dateTo
required
string <date>

Latest creation date to include (ISO 8601 date)

statuses
Array of strings
Items Enum: "INITIAL" "IN_PROGRESS" "REJECTED" "APPROVED" "COMPLETED"

Optional list of nomination statuses to filter by

marketingAdminUuids
Array of strings

Optional list of marketing admin UUIDs to filter by

nominationUuids
Array of strings

Optional list of specific nomination UUIDs to return

salespersonNames
Array of strings

Optional list of salesperson names to filter by

activityTypeNames
Array of strings

Optional list of activity type names to filter by

searchQuery
string

Optional free-text search query across nomination fields

includeRepeatedNominations
boolean

Include nominations that have been requested for the same advocate multiple times

Responses

Request samples

Content type
application/json
{
  • "dateFrom": "2026-01-01",
  • "dateTo": "2026-03-31",
  • "statuses": [
    ],
  • "marketingAdminUuids": [
    ],
  • "nominationUuids": [
    ],
  • "salespersonNames": [
    ],
  • "activityTypeNames": [
    ],
  • "searchQuery": "renewal",
  • "includeRepeatedNominations": false
}

Content Categories

Manage categories that group content tags.

Update content category

Update an existing content category. Only present fields are changed — omit a field to leave it untouched.

Setting tagUuids replaces the full set of tags in this category (it is not an add-list). Tags removed from the set lose their category but are not deleted.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/content-categories/660e8400-e29b-41d4-a716-446655440111' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "description": "Updated description for technology",
    "tagUuids": ["550e8400-e29b-41d4-a716-446655440000"]
  }'
Authorizations:
bearer-jwt
path Parameters
uuid
required
string

UUID of the category to update

Request Body schema: application/json
required
uuid
string

UUID of the category to update

name
string [ 1 .. 255 ] characters

Optional new category name (1 to 255 characters)

description
string

Optional new description

tagUuids
Array of strings[ items non-empty ]

Optional new list of tag UUIDs to include in this category

Responses

Request samples

Content type
application/json
{
  • "uuid": "660e8400-e29b-41d4-a716-446655440111",
  • "name": "Updated Technology",
  • "description": "Updated description for technology",
  • "tagUuids": [
    ]
}

Delete content category

Delete an existing content category. Tags previously in this category are not deleted; they become uncategorized (you can re-assign them to another category via Update Content Tag).

Example:

curl -X DELETE 'https://prod.customershome.com/acauth/api/v1/content-categories/660e8400-e29b-41d4-a716-446655440111' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
path Parameters
uuid
required
string

UUID of the category to delete

Responses

Bulk update content categories

Update multiple content categories in a single request. The body is a map keyed by category UUID, so each entry follows the same semantics as the single-update endpoint (notably: tagUuids is a full replace, not a merge). Up to 100 entries per request.

Each entry is processed independently — inspect successful and failed in the response.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/content-categories/bulk' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "660e8400-e29b-41d4-a716-446655440111": {
      "description": "Updated tech description"
    },
    "660e8400-e29b-41d4-a716-446655440222": {
      "tagUuids": ["tag-uuid-5", "tag-uuid-6"]
    }
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
additional property
object (UpdateContentTagCategory)

Payload for updating an existing content category. Only present fields are changed.

Responses

Request samples

Content type
application/json
{
  • "property1": {
    },
  • "property2": {
    }
}

Bulk create content categories

Create multiple content categories in a single request. Accepts 1 to 100 items; each item is processed independently. The response separates successful and failed items so a partial success is still a 201 — inspect the body.

Useful when migrating a content taxonomy from another system in one shot rather than looping on the single-create endpoint.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/content-categories/bulk' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '[
    { "name": "Technology", "description": "Tech content", "tagUuids": ["tag-uuid-1"] },
    { "name": "Marketing", "description": "Marketing content", "tagUuids": ["tag-uuid-2"] }
  ]'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
Array
name
required
string [ 1 .. 255 ] characters

Category display name. Required; 1 to 255 characters.

description
string

Optional human-readable description of the category

tagUuids
required
Array of strings

Tag UUIDs to include in this category. At least one is required.

Responses

Request samples

Content type
application/json
[
  • {
    }
]

List content categories

Retrieve a paginated list of content categories with optional substring name filtering. Use the returned uuid of each category to scope a subsequent List Content Tags call to that category.

Maximum page size is 500; requests above that limit return 400.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/content-categories?name=tech&page=0&size=20' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
name
string

Filter categories by name (substring match)

required
object (Pageable)

Responses

Create content category

Create a new content category and assign one or more existing tags to it. name must be unique within the company; tagUuids is required and must contain at least one tag.

If you need to create the tags first, call Create Content Tag (or its bulk variant) before this endpoint.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/content-categories' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Technology",
    "description": "All technology-related content",
    "tagUuids": ["550e8400-e29b-41d4-a716-446655440000", "550e8400-e29b-41d4-a716-446655440001"]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
name
required
string [ 1 .. 255 ] characters

Category display name. Required; 1 to 255 characters.

description
string

Optional human-readable description of the category

tagUuids
required
Array of strings

Tag UUIDs to include in this category. At least one is required.

Responses

Request samples

Content type
application/json
{
  • "name": "Technology",
  • "description": "All technology-related content",
  • "tagUuids": [
    ]
}

Content Tags

Manage tags used to categorize content within the platform.

Update content tag

Update the description and/or category of an existing content tag. The tag name is immutable via this endpoint; create a new tag and delete the old one if you need to rename.

Pass tagCategoryUuid: null to move the tag back to top-level.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/content-tags/550e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "description": "Updated description",
    "tagCategoryUuid": "660e8400-e29b-41d4-a716-446655440222"
  }'
Authorizations:
bearer-jwt
path Parameters
uuid
required
string

UUID of the tag to update

Request Body schema: application/json
required
description
string

Optional new description of the tag

tagCategoryUuid
string

Optional new parent content category UUID

Responses

Request samples

Content type
application/json
{
  • "description": "Updated description",
  • "tagCategoryUuid": "660e8400-e29b-41d4-a716-446655440111"
}

Delete content tag

Delete an existing content tag. The tag is removed from every content item that referenced it; the content items themselves are not deleted. Deleting a tag that does not exist returns 404 — handle the not-found case explicitly if your sync runs may already have removed the tag.

Example:

curl -X DELETE 'https://prod.customershome.com/acauth/api/v1/content-tags/550e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
path Parameters
uuid
required
string

UUID of the tag to delete

Responses

Bulk update content tags

Update multiple content tags in a single request. The body is a map keyed by tag UUID, so the same description / tagCategoryUuid semantics as the single-update endpoint apply per entry. Up to 100 entries per request.

Each entry is processed independently — inspect successful and failed in the response to find out which entries committed. Useful for re-categorizing tags in bulk, e.g. moving all tags from a deprecated category to a new one.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/content-tags/bulk' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "550e8400-e29b-41d4-a716-446655440000": {
      "tagCategoryUuid": "660e8400-e29b-41d4-a716-446655440222"
    },
    "550e8400-e29b-41d4-a716-446655440001": {
      "description": "Updated description"
    }
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
additional property
object (UpdateContentTag)

Payload for updating an existing content tag. Only present fields are changed.

Responses

Request samples

Content type
application/json
{
  • "property1": {
    },
  • "property2": {
    }
}

Bulk create content tags

Create multiple content tags in a single request. Accepts 1 to 100 items; each item is processed independently. The response contains a successful array of newly created UUIDs and a failed array with per-item error context (most commonly a DUPLICATE_NAME error when the tag already exists).

A partial failure (some items in failed) is still a 200 response — inspect the body to find out which items were created. Use this endpoint when seeding a new company or importing tags from a CRM rather than calling the single-create endpoint in a loop.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/content-tags/bulk' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '[
    { "name": "Product Launch", "tagCategoryUuid": "660e8400-e29b-41d4-a716-446655440111" },
    { "name": "Customer Success" }
  ]'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
Array
name
required
string [ 1 .. 255 ] characters

Tag display name. Required; 1 to 255 characters.

description
string

Optional human-readable description of the tag

tagCategoryUuid
string

Optional UUID of the parent content category

Responses

Request samples

Content type
application/json
[
  • {
    }
]

List content tags

Retrieve a paginated list of content tags with optional filtering by name (substring match) and category UUID.

Typical flow: list categories first to obtain contentCategoryUuid, then list tags scoped to that category. Maximum page size is 500; requests above that limit return 400.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/content-tags?contentCategoryUuid=660e8400-e29b-41d4-a716-446655440111&page=0&size=50' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
name
string

Filter tags by name (substring match)

contentCategoryUuid
string

Filter tags by content category UUID

required
object (Pageable)

Responses

Create content tag

Create a new content tag.

name is required and must be unique within the company (case-insensitive). Pass a tagCategoryUuid to put the new tag under an existing category, or leave it null to create a top-level tag. The response body returns the new UUID; use it as the identifier for subsequent update or delete calls.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/content-tags' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Product Launch",
    "description": "Used to mark content related to product launch campaigns",
    "tagCategoryUuid": "660e8400-e29b-41d4-a716-446655440111"
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
name
required
string [ 1 .. 255 ] characters

Tag display name. Required; 1 to 255 characters.

description
string

Optional human-readable description of the tag

tagCategoryUuid
string

Optional UUID of the parent content category

Responses

Request samples

Content type
application/json
{
  • "name": "Product Launch",
  • "description": "Used to mark content related to product launch campaigns",
  • "tagCategoryUuid": "660e8400-e29b-41d4-a716-446655440111"
}

Company API

Core customer-facing V1 endpoints: users, advocates, accounts, opportunities, activities, leaderboard, points, imports, and registration confirmation.

Get user data

Get full data for a single user by external auth id (the identifier issued by the SSO provider — not the email and not the advocate UUID). Returns 404 if the user does not exist in the caller's company.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/users/auth0|abcd1234' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
path Parameters
id
required
string

External auth id of the user

Responses

Update user data

Update custom attribute values for an existing user identified by external SSO auth id. The payload mirrors Modify custom attributes for a single advocate — three optional maps for addCustomAttributes, updateCustomAttributes, and removeCustomAttributes. The endpoint does not change profile fields (name, email, jobTitle, company) directly; profile fields are managed via the registration / SSO flow.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/users/auth0|abcd1234' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "updateCustomAttributes": { "favorite_color": ["green"] },
    "removeCustomAttributes": ["deprecated_flag"]
  }'
Authorizations:
bearer-jwt
path Parameters
id
required
string

External auth id of the user

Request Body schema: application/json
required
object
object
removeCustomAttributes
Array of strings

Responses

Request samples

Content type
application/json
{
  • "addCustomAttributes": {
    },
  • "updateCustomAttributes": {
    },
  • "removeCustomAttributes": [
    ]
}

Grant points

Grant points (and optionally badges) to an advocate identified by email. Use a sensible reason string — it shows up in the advocate's points history and in admin audit logs.

Common use cases: bonus award, custom one-off recognition, retroactive correction after a missed activity. For automatic point-per-activity recognition, prefer wiring an activity type with a points reward and calling Trigger activity instead.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/points/grant-points' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "ada@example.com",
    "points": 250,
    "reason": "Spoke on the customer panel at SaaSCon 2026"
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
email
required
string <email> non-empty
points
required
integer <int32>
credit
integer <int32>
reason
required
string non-empty

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "points": 0,
  • "credit": 0,
  • "reason": "string"
}

Get advocate custom attribute values

Get custom attribute values for one or more advocates. Pass a comma-separated list of advocate UUIDs as uuids; omit to return values for all advocates in the company (use with care on large tenants).

The response is a map keyed by advocate UUID; each value is an array of attribute readings. Combine with List custom attributes (entity=contact) to interpret what each attribute means.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/advocate/custom-attributes?uuids=550e8400-e29b-41d4-a716-446655440000,550e8400-e29b-41d4-a716-446655440001' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
uuids
string

Optional comma-separated list of advocate UUIDs to filter by

Responses

Modify advocate custom attributes

Update one or more custom attribute values on a single advocate identified by email. The request carries an array of {attributeName, values} rows — each row sets the values of one custom attribute (values is always an array; for single-value attributes pass a one-element array).

The response is an array of per-update result rows. Either attributeName or attributeUuid may be used to identify the attribute. Use the per-advocate-id variant (PUT /advocate/custom-attributes/{id}) when you already have the SSO auth id rather than the email.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/advocate/custom-attributes' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "ada@example.com",
    "attributes": [
      { "attributeName": "favorite_color", "values": ["blue"] },
      { "attributeName": "role", "values": ["VP Engineering"] }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
Array of objects (AttributeUpdateDTO)
email
required
string <email> non-empty

Responses

Request samples

Content type
application/json
{
  • "attributes": [
    ],
  • "email": "user@example.com"
}

Modify custom attributes for a single advocate

Update custom attribute values for a single advocate identified by external auth id. The payload is partitioned into three maps so a single call can add, update, and remove attributes atomically:

  • addCustomAttributes{ "<attributeName>": ["value1", "value2"] } — add the given values (no-op if the attribute already holds them).
  • updateCustomAttributes{ "<attributeName>": ["value1", "value2"] } — replace the attribute's full value set with the supplied array.
  • removeCustomAttributes["<attributeName>", ...] — remove the attribute entirely.

The response returns the resulting list of attribute values on the advocate. The companion PUT /advocate/custom-attributes endpoint targets the advocate by email + a flat [{attributeName, values}] array — use whichever identifier you already have on hand.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/advocate/custom-attributes/auth0|abcd1234' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "updateCustomAttributes": { "favorite_color": ["green"] }
  }'
Authorizations:
bearer-jwt
path Parameters
id
required
string

External auth id of the advocate

Request Body schema: application/json
required
object
object
removeCustomAttributes
Array of strings

Responses

Request samples

Content type
application/json
{
  • "addCustomAttributes": {
    },
  • "updateCustomAttributes": {
    },
  • "removeCustomAttributes": [
    ]
}

List users

List users (advocates) in the caller's company. Pass emails (comma-separated set) to look up specific advocates by email. Returns a basic projection — for full advocate data including custom attributes and consent, use List advocates instead.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/users?emails=ada@example.com,alan@example.com&page=0&size=20' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
emails
Array of strings unique

Optional set of emails to filter by

required
object (Pageable)

Responses

Create user

Create a new advocate user in the caller's company. Email is unique per company — if the email already exists in this company the response is 400 with body EMAIL_CONFLICT.

The new user is created in an unactivated state; standard onboarding flows (invitation email, activation link) fire automatically. Use Import contacts by email for bulk onboarding instead of looping on this endpoint.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/users' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "ada@example.com",
    "firstName": "Ada",
    "lastName": "Lovelace",
    "jobTitle": "Chief Computing Officer"
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
accountName
string
firstName
required
string non-empty
lastName
string
captcha
string
email
required
string <email> non-empty
login
string
customEmailMessage
string
fromRegisterLead
boolean
register
boolean
muteRegisterEmail
boolean
bonusPoints
integer <int32>
authId
string
companyUuid
string
targetCrowdId
string
traceUuid
string
utmId
string
utmSource
string
anonymousAdvocateUuid
string
advocateTimezoneOffset
integer <int32>
joinMethod
string
Enum: "INVITE" "REQUEST" "AUTO_SIGNUP" "REFERRAL" "IMPORT" "SSO" "NOMINATE" "API" "INTEGRATION" "DATA_SYNC"
object (NominationDetails)

Responses

Request samples

Content type
application/json
{
  • "accountName": "string",
  • "firstName": "string",
  • "lastName": "string",
  • "captcha": "string",
  • "email": "user@example.com",
  • "login": "string",
  • "customEmailMessage": "string",
  • "fromRegisterLead": true,
  • "register": true,
  • "muteRegisterEmail": true,
  • "bonusPoints": 0,
  • "authId": "string",
  • "companyUuid": "string",
  • "targetCrowdId": "string",
  • "traceUuid": "string",
  • "utmId": "string",
  • "utmSource": "string",
  • "anonymousAdvocateUuid": "string",
  • "advocateTimezoneOffset": 0,
  • "joinMethod": "INVITE",
  • "nominationDetails": {
    }
}

Trigger activity

Trigger a tracked activity for an advocate identified by email. The activity is recorded against the advocate and may award points, progress an open ASK, fire downstream automation, or all three depending on how the activity type is configured in admin.

Common patterns: a CRM sync calling this when an opportunity closes, a content platform calling it when an advocate posts a review, a webhook bridge translating third-party events into Base activities. Use List activity types to discover valid activity types beforehand.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/trigger-activity' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "ada@example.com",
    "apiIdentifier": "case_study_published"
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
email
required
string <email> non-empty
apiIdentifier
string^[a-z0-9_]{1,50}$

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "apiIdentifier": "string"
}

Registration confirmation

Confirm that an advocate directed from the Base system completed registration. Call this from your registration landing page after the advocate's account is provisioned so Base can attribute the registration to the originating UTM campaign and capture profile fields submitted on the form.

utmCampaign is required and is the campaign id Base appended to the registration URL as ?utm_campaign=<id>. Other fields (firstName, lastName, jobTitle, tags, etc.) are optional and fall back to whatever was supplied earlier in the flow.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/registration-confirmation' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "utmCampaign": "spring-2026-launch",
    "step": 2,
    "utmSource": "linkedin",
    "tags": ["enterprise", "early-adopter"],
    "firstName": "Ada",
    "lastName": "Lovelace",
    "company": "Analytical Engines Inc.",
    "jobTitle": "Chief Computing Officer",
    "email": "ada@example.com"
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
utmCampaign
required
string
step
required
integer <int32> [ 2 .. 3 ]
advocateUuid
string
utmSource
string
tags
Array of strings
firstName
string
lastName
string
company
string
jobTitle
string
email
string

Responses

Request samples

Content type
application/json
{
  • "utmCampaign": "string",
  • "step": 2,
  • "advocateUuid": "string",
  • "utmSource": "string",
  • "tags": [
    ],
  • "firstName": "string",
  • "lastName": "string",
  • "company": "string",
  • "jobTitle": "string",
  • "email": "string"
}

Upsert opportunity attributes

Create or update one or more opportunities and their custom attribute values in a single call. The request body wraps a list of opportunity items; each item is identified by opportunityId (the external CRM id, required). If no matching opportunity exists in Base the item creates one; otherwise it updates the existing one in place.

Typical use: a CRM sync job that pushes the latest opportunity state into Base. customAttributes follows the same [{attributeName, values}] shape used elsewhere in the V1 API.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/opportunity-attributes' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "opportunities": [
      {
        "opportunityId": "006Aa00001ABcDE",
        "opportunityName": "Acme renewal — FY26",
        "opportunityStage": "Closed Won",
        "opportunityAmount": 75000,
        "opportunityProbability": 100,
        "opportunityIsWon": true,
        "opportunityCloseDate": "2026-05-15",
        "customAttributes": [
          { "attributeName": "renewal_reason", "values": ["Expansion"] }
        ]
      }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
Array of objects (OpportunityUpdateRequestBodyDTO)

Responses

Request samples

Content type
application/json
{
  • "opportunities": [
    ]
}

Import reference contacts by contact ID

Import reference advocates — advocates designated to act as references for sales conversations — by external CRM contact id. Returns per-row results.

Distinct from regular Import contacts by contact ID: the imported records are flagged as available for the reference-request flow even if they are not active advocates in the usual points-and-asks sense.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/advocate/reference/import-by-contact-id' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '[
    { "contactId": "003Aa00001ABcDE", "frequency": "ANYTIME" },
    { "contactId": "003Aa00001ABcDF" }
  ]'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
Array
contactId
required
string non-empty
register
boolean
sendInvite
boolean
Array of objects (ExternalConsentDTO)
referencePool
string
frequency
string

Responses

Request samples

Content type
application/json
[
  • {
    }
]

Import contacts by email

Import advocates by email. Each item is processed independently; the response is an array of per-row outcomes.

Email is matched case-insensitively against existing advocates — duplicate rows are surfaced as per-row errors rather than dropped silently. Use for bulk onboarding when email is the only durable identifier you have for the source records.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/advocate/import-by-email' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '[
    {
      "email": "ada@example.com",
      "firstName": "Ada",
      "lastName": "Lovelace",
      "accountName": "Analytical Engines Inc.",
      "register": true,
      "sendInvite": false
    }
  ]'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
Array
email
required
string <email> [ 0 .. 127 ] characters
firstName
required
string [ 0 .. 50 ] characters
lastName
required
string [ 0 .. 50 ] characters
accountName
required
string [ 0 .. 255 ] characters
register
boolean
sendInvite
boolean
Array of objects (ExternalConsentDTO)
referencePool
string

Responses

Request samples

Content type
application/json
[
  • {
    }
]

Import contacts by contact ID

Import advocates by external CRM contact id. Each item in the request body is processed independently — failures on one row do not abort the rest. The response is an array of per-row outcomes (success with new advocate UUID, or per-row error).

Use for bulk onboarding from a CRM where the contact id is the durable identifier. Pair with Import contacts by email when some rows lack a CRM id but have a verified email.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/advocate/import-by-contact-id' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '[
    { "contactId": "003Aa00001ABcDE", "register": true, "sendInvite": false },
    { "contactId": "003Aa00001ABcDF" }
  ]'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
Array
contactId
required
string non-empty
register
boolean
sendInvite
boolean
Array of objects (ExternalConsentDTO)
referencePool
string

Responses

Request samples

Content type
application/json
[
  • {
    }
]

Get account data

Retrieve a paginated list of accounts (with their core fields and custom attribute values). Optionally narrow the result to specific accounts via uuids (up to 500 per request). Repeat the parameter (uuids=A&uuids=B) or pass a comma-separated value (uuids=A,B) — both are accepted by the Spring binding.

Maximum page size is 500. Use for CRM-sync workflows that need to mirror Base account state back to another system.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/account?uuids=550e8400-e29b-41d4-a716-446655440000&uuids=550e8400-e29b-41d4-a716-446655440001&page=0&size=50' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
uuids
Array of strings [ 0 .. 500 ] items

Optional list of up to 500 account UUIDs to filter by

required
object (Pageable)

Responses

Update account data

Create or update an account ("upsert"). At least one of uuid or name must be supplied — when only name is supplied a new account is created if no match exists, otherwise the existing matching account is updated.

Other fields are optional: domain (lowercase hostname like example.com), sizeFrom / sizeTo (numeric employee-count range), industryType (free-form), and customAttributeValues as a list of {name, values} rows for any custom attributes defined on the account entity.

Example (create new account):

curl -X POST 'https://prod.customershome.com/acauth/api/v1/account' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Analytical Engines Inc.",
    "domain": "analyticalengines.com",
    "sizeFrom": 100,
    "sizeTo": 500,
    "industryType": "Software",
    "customAttributeValues": [
      { "name": "tier", "values": ["Enterprise"] }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
uuid
string
name
string
domain
string^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,6}$
sizeFrom
integer <int32>
sizeTo
integer <int32>
industryType
string
Array of objects (CustomDataAttributeValueDTO)

Responses

Request samples

Content type
application/json
{
  • "uuid": "string",
  • "name": "string",
  • "domain": "string",
  • "sizeFrom": 0,
  • "sizeTo": 0,
  • "industryType": "string",
  • "customAttributeValues": [
    ]
}

List users modified since

List users (advocates) filtered by source external system and an optional modified-since cutoff. Designed for incremental sync: poll with sinceLastModified set to the previous successful sync timestamp to fetch only the diff.

externalSystem is required and identifies which integration sourced the users (CRM, marketing automation, etc.).

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/users-by-dates?externalSystem=SalesForce&sinceLastModified=2026-05-01T00:00:00&page=0&size=100' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
externalSystem
required
string
Enum: "SalesForce" "HubSpot" "Oracle" "External" "Test"

External system identifying the source of users to filter

sinceLastModified
string <date-time>

Optional ISO 8601 cutoff; only users modified at or after this time are returned

required
object (Pageable)

Responses

Get API status

Returns basic status information including the caller's company name. Use this as a cheap connectivity / auth check from your integration before issuing real requests — a 200 response confirms the bearer token is valid and bound to a company.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/status' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt

Responses

Get opportunity data

Retrieve a paginated list of opportunities (with their core fields and custom attribute values). Optionally narrow to specific opportunities via uuids (up to 500 per request). Repeat the parameter (uuids=A&uuids=B) or pass a comma-separated value (uuids=A,B).

Maximum page size is 500. Use for CRM-sync workflows that need to read Base's opportunity state.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/opportunity?uuids=550e8400-e29b-41d4-a716-446655440000&page=0&size=50' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
uuids
Array of strings [ 0 .. 500 ] items

Optional list of up to 500 opportunity UUIDs to filter by

required
object (Pageable)

Responses

Get opportunity attributes

Read an opportunity and its custom attribute values by external CRM opportunity id (not the Base internal UUID). Useful when your CRM is the source of truth and you want to verify what Base currently has stored.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/opportunity-attributes/006Aa00001ABcDE' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
path Parameters
id
required
string

External (CRM) opportunity id

Responses

Get leaderboard

Retrieve a paginated leaderboard of advocates ranked by points (highest first). Set email=true to include each advocate's email in the response — by default it is omitted so the payload is safe to embed in a public-facing UI.

Use Spring pagination (page, size) to walk the leaderboard; the underlying ordering is stable across pages.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/leaderboard?page=0&size=20' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
email
boolean

Whether to include email addresses for each advocate (default false)

required
object (Pageable)

Responses

Get leaderboard entry by email

Return the leaderboard entry for a single advocate identified by email. Useful when embedding an advocate's own rank/points in an in-product widget without walking the full leaderboard.

Returns 404 if the advocate or company cannot be resolved.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/leaderboard-by-email?email=ada@example.com' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
email
required
string

Email of the advocate to look up

Responses

List ASKs

Retrieve a paginated list of ASKs defined in the company. (ASK is the customer-facing label for what the API calls challenge — see the intro for the terminology mapping.)

Maximum page size is 500. Returns active and inactive ASKs alike; filter by status / type on the client side if needed.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/challenge?page=0&size=50' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
required
object (Pageable)

Responses

List advocates

Retrieve a paginated list of advocates with their account and consent information. Optionally filter by a single advocate UUID or email.

Maximum page size is 500; requests above that limit return 400. Use this rather than List users when you need account linkage, custom attribute values, or consent flags. Combine with since-style filtering on related endpoints for incremental sync into your CRM.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/advocate?email=ada@example.com&page=0&size=50' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
uuid
string

Optional advocate UUID to filter to a single record

email
string

Optional advocate email to filter to a single record

required
object (Pageable)

Responses

Get advocate custom object attribute values

Read custom object records and their attribute values for one advocate. Identify the advocate by UUID or email (one of the two is required); identify the custom object type by objectName (its apiName from the mapping).

Without instanceId, returns every record of that object type attached to the advocate. With instanceId, narrows the response to a single record. Use the listing form first to discover instance IDs, then drill in for the data you need.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/advocate/custom-object-record/subscription?advocateEmail=ada@example.com' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
path Parameters
objectName
required
string

API name of the custom object

query Parameters
advocateUuid
string

UUID of the target advocate (either advocateUuid or advocateEmail is required)

advocateEmail
string

Email of the target advocate (either advocateUuid or advocateEmail is required)

instanceId
string

Optional instance ID to narrow to a specific custom object record

Responses

List advocate custom attribute field values

List external-entity field values for selected custom attribute fields across advocates. Use fieldNames to scope the query to specific attributes and sinceLastModified (ISO-8601 UTC) to fetch only the values that changed at or after that time.

Designed for incremental sync: poll with sinceLastModified = "last successful sync timestamp" to pull only the diff rather than the full universe of values.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/advocate/custom-attributes/field-value?fieldNames=favorite_color,role&sinceLastModified=2026-05-01T00:00:00Z&page=0&size=100' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
fieldNames
Array of strings

Optional list of custom attribute field names to return

sinceLastModified
string <date-time>

Optional ISO 8601 cutoff; only field values modified at or after this time are returned

required
object (Pageable)

Responses

List activities

Retrieve a paginated list of activity records (advocate actions tracked by Base). Each activity references an advocate, an activity type, and a timestamp. Use for analytics export or to populate an activity feed in your own UI.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/activity?page=0&size=50' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
required
object (Pageable)

Responses

List activity types

Return all activity types defined in the caller's company. Each activity type has a stable name that you pass to Trigger activity.

Cache the result on your side — activity types change rarely (admin configuration), and calling this on every Trigger activity request is wasteful.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/activity-types' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt

Responses

Delete user by ID

Delete an advocate by external auth id (the SSO-issued identifier). Same security/no-enumeration semantics as Delete user by email: returns 204 for both "deleted" and "not found". A 500 indicates the delete itself failed downstream. The deletion is permanent.

Example:

curl -X DELETE 'https://prod.customershome.com/acauth/api/v1/users-by-id?id=auth0|abcd1234' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
id
required
string

External auth id of the user to delete

Responses

Delete user by email

Delete an advocate by email. For security reasons the endpoint does not disclose whether the user existed — it returns 204 No Content for both "deleted" and "not found" to prevent email enumeration. A 500 indicates the delete itself failed downstream.

The deletion cascades to consent records, custom attribute values, points history, and ASK progress; the advocate cannot be recovered.

Example:

curl -X DELETE 'https://prod.customershome.com/acauth/api/v1/users-by-email?email=ada@example.com' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
email
required
string

Email of the user to delete

Responses

Custom Object Mappings

Define and manage custom object types (mappings) and the attributes on those objects.

Update custom object mapping

Update the human-readable label/description of an existing custom object mapping. The apiName, owning entity, and the attributes defined on the object are immutable via this endpoint — use the Custom Attributes endpoints to add or remove fields.

Example:

curl -X PUT 'https://prod.customershome.com/acauth/api/v1/custom-object-mapping/primary_contact' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "label": "Primary contact",
    "description": "Updated description"
  }'
Authorizations:
bearer-jwt
path Parameters
apiName
required
string

API name of the mapping to update

Request Body schema: application/json
required
label
required
string [ 1 .. 128 ] characters

Human-readable label for the custom object

description
string [ 0 .. 100 ] characters

Optional description (max 100 characters)

Responses

Request samples

Content type
application/json
{
  • "label": "Primary Contact",
  • "description": "Primary point of contact at the account"
}

Delete custom object mapping

Delete a custom object mapping by apiName. All records of this custom object type across every advocate/account/opportunity in the company are deleted along with their attribute values.

Irreversible — use with care.

Example:

curl -X DELETE 'https://prod.customershome.com/acauth/api/v1/custom-object-mapping/primary_contact' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
path Parameters
apiName
required
string

API name of the mapping to delete

Responses

List custom object mappings

List custom object mappings (and their attributes) for a given entity. A "mapping" describes a custom object type (e.g. primary_contact, subscription) that you can attach to advocates, accounts, or opportunities.

Use this to discover what custom object types are available before creating / reading records.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/custom-object-mapping?entity=account' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
entity
required
string
Enum: "contact" "account" "opportunity" "nomination"

Entity owning the custom objects (advocate, account, opportunity, etc.)

Responses

Create custom object mapping

Define a new custom object mapping on an entity. apiName is the immutable identifier used in all subsequent record-level calls (URL path parameter, query payloads), so choose carefully — typically lowercase singular noun like subscription or meeting. label is the human-readable display used in admin UIs.

After this returns, define the attributes on the new custom object via Create Custom Attribute (with entity set to the new mapping's apiName).

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/custom-object-mapping' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "apiName": "primary_contact",
    "label": "Primary Contact",
    "description": "Primary point of contact at the account",
    "entity": "account"
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
label
required
string [ 1 .. 128 ] characters

Human-readable label for the custom object

description
string [ 0 .. 100 ] characters

Optional description (max 100 characters)

apiName
required
string [ 1 .. 64 ] characters ^(?!.*\s)[a-z0-9_]+$

Internal API name. 1 to 64 characters, lowercase letters/digits/underscores only.

entity
required
string
Enum: "contact" "account" "opportunity" "nomination"

Entity that owns this custom object

Responses

Request samples

Content type
application/json
{
  • "label": "Primary Contact",
  • "description": "Primary point of contact at the account",
  • "apiName": "primary_contact",
  • "entity": "contact"
}

List custom object attributes

List attributes that exist on a custom object related to a given entity. entityRelation is the relation key declared when the custom object was mapped (e.g. primary_contact for a Contact object related to an Account).

Returned by Get Account Custom Object Attribute Values / advocate equivalent before you read or write per-record values.

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/custom-object-attributes?entityRelation=primary_contact' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
entityRelation
required
string

Relation name identifying the custom object on the entity

Responses

Reference Requests

Submit, list, and retrieve reference requests, and find reference advocates.

List reference requests

Retrieve a paginated list of reference requests matching the provided filter (deadline range, statuses, requester, etc.). Use this for reporting dashboards or to find the UUID of a specific request to read in detail.

Maximum page size is 100. Sort using the standard Spring sort query parameter (e.g. sort=createdAt,desc).

Example:

curl -X GET 'https://prod.customershome.com/acauth/api/v1/reference-requests?page=0&size=50&sort=createdAt,desc' \
  -H 'Authorization: Bearer <jwt_token>'
Authorizations:
bearer-jwt
query Parameters
required
object (ReferenceRequestFilterDTO)

Filter criteria for narrowing the result set: date range, statuses, requester, etc. See ReferenceRequestFilterDTO for the field list.

size
required
integer <int32> [ 1 .. 100 ]
page
required
integer <int32> >= 0
required
object (Pageable)

Responses

Submit reference request

Submit a new reference request. The body must specify an opportunity, opportunity contact, requester, reference manager, and 1–10 reference entries. All entries must be the same type — either all source-contact (sourced from your CRM) or all P2P (an existing advocate acting as reference). Mixed types are rejected.

Returns 204 No Content on success; downstream notifications and workflows pick up the request asynchronously.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/reference-requests' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "deadline": "2026-06-01T00:00:00Z",
    "subject": "Reference for Acme renewal",
    "referenceTypeUuid": "550e8400-e29b-41d4-a716-446655440000",
    "notes": "Looking for a 30-minute peer reference call.",
    "opportunity": {
      "opportunityId":          "006Aa00001ABcDE",
      "opportunityName":        "Acme renewal — FY26",
      "opportunityAccountId":   "001Aa00001A2B3C",
      "opportunityAccountName": "Acme Corp"
    },
    "opportunityContact": {
      "externalId": "003Aa00001ABcDE",
      "firstName":  "Bob",
      "lastName":   "Buyer",
      "email":      "buyer@acme.example"
    },
    "requester": {
      "externalId": "005Aa00001ZyXwV",
      "firstName":  "Sara",
      "lastName":   "Sales",
      "email":      "rep@yourcompany.example"
    },
    "referenceManager": { "uuid": "660e8400-e29b-41d4-a716-446655440111" },
    "entries": [
      {
        "externalId":      "rr-2026-q2-001",
        "crmRequestNumber": "REQ-12345",
        "advocate":        { "uuid": "770e8400-e29b-41d4-a716-446655440222" }
      }
    ]
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
deadline
required
string <date-time>

Deadline by which the reference should be completed

subject
required
string

Short subject line describing the reference request

referenceTypeUuid
required
string

UUID of the reference type (e.g. case study, peer call) from the form configuration

notes
string

Internal-only notes shown to the reference manager / sales team

notesForReference
string

Notes shown to the reference advocate when invited

required
object (OpportunityDTO)

Opportunity the reference is requested for

required
object (ExternalActorDTO)

Contact person on the opportunity (typically the buyer)

required
object (ExternalActorDTO)

Person who requested the reference (salesperson in CRM)

required
object (BaseActorDTO)

Reference manager assigned to coordinate the request

required
Array of objects (RequestEntryDTO) [ 1 .. 10 ] items

1–10 reference entries; all must be source-contact OR all P2P (cannot be mixed)

Array of objects (ReportCustomAttributesFiltersDTO)

Optional custom-attribute filters captured at request time (used by the custom-element reference form)

Responses

Request samples

Content type
application/json
{
  • "deadline": "2026-06-01T00:00:00Z",
  • "subject": "Reference for Acme renewal",
  • "referenceTypeUuid": "string",
  • "notes": "string",
  • "notesForReference": "string",
  • "opportunity": {
    },
  • "opportunityContact": {
    },
  • "requester": {
    },
  • "referenceManager": {
    },
  • "entries": [
    ],
  • "matchCriteria": [
    ]
}

Read reference request form settings

Retrieve the configuration of the reference request form: which fields are enabled, their labels, available reference types, allowed reference managers, custom attributes to display, and contact / weighting options. The configuration is computed from the supplied context — pass the CRM account, opportunity, and intended reference type so the response reflects the rules that apply to that specific combination.

Call this first to render the form UI or to know which fields are valid before submitting a reference request.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/reference-requests/form' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "context": {
      "account":     { "id": "001Aa00001A2B3C", "name": "Acme Corp",                "industry": "Software" },
      "opportunity": { "id": "006Aa00001ABcDE", "name": "Acme renewal — FY26",     "accountId": "001Aa00001A2B3C", "stage": "Negotiation" },
      "referenceTypeUuid": "550e8400-e29b-41d4-a716-446655440000"
    }
  }'
Authorizations:
bearer-jwt
Request Body schema: application/json
required
object (ReferenceRequestContext)

Context in which the form is being requested (controls which fields/options are returned)

Responses

Request samples

Content type
application/json
{
  • "context": {
    }
}

Read reference advocates report

Retrieve a paginated list of advocates eligible to be referenced, ranked by the weighted criteria supplied in the request body. Use this to pre-populate a "best matches" list when building a reference request UI, or to feed an internal sales-tooling dashboard.

Maximum page size is 100. The weighting model considers industry / role overlap, recent activity, consent, and any custom attribute filters you pass.

Example:

curl -X POST 'https://prod.customershome.com/acauth/api/v1/reference-advocates/report?page=0&size=20' \
  -H 'Authorization: Bearer <jwt_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "industryTypes":   { "value": [12, 47],          "weight": 5 },
    "jobTitles":       { "value": ["VP Engineering"], "weight": 4 },
    "accountSizeFrom": { "value": 100,                "weight": 2 },
    "accountSizeTo":   { "value": 5000,               "weight": 2 },
    "customAttributes": [
      {
        "id":     "aa11bb22-cc33-dd44-ee55-ff6677889900",
        "name":   "favorite_color",
        "entity": "contact",
        "values": ["blue"],
        "weight": 1
      }
    ],
    "referenceTypeUuid": "550e8400-e29b-41d4-a716-446655440000",
    "reportSize": 50
  }'
Authorizations:
bearer-jwt
query Parameters
size
required
integer <int32> [ 1 .. 100 ]
page
required
integer <int32> >= 0
required
object (Pageable)
Request Body schema: application/json
required
object (WeightedFilterParameterDTOListLong)
object (WeightedFilterParameterDTOListLong)
object (WeightedFilterParameterDTOListLong)
object (WeightedFilterParameterDTOListString)
object (WeightedFilterParameterDTOLong)
object (WeightedFilterParameterDTOLong)
object (WeightedFilterParameterDTOListString)
object (WeightedFilterParameterDTOListString)
includeGroupedAttributes
boolean
Array of objects (ReportCustomAttributesFiltersDTO)
object
challengeUuid
string
advocateUuid
string
opportunityId
string
object (WeightedFilterParameterDTOListString)
hasExternalId
boolean
referenceTypeUuid
string
searchCriteria
string
reportSize
integer <int32>

Responses

Request samples

Content type
application/json
{
  • "seniorityLevels": {
    },
  • "geographicalLocations": {
    },
  • "industryTypes": {
    },
  • "jobTitles": {
    },
  • "accountSizeFrom": {
    },
  • "accountSizeTo": {
    },
  • "productsAndServices": {
    },
  • "useCases": {
    },
  • "includeGroupedAttributes": true,
  • "customAttributes": [
    ],
  • "customObjectAttributes": {
    },
  • "challengeUuid": "string",
  • "advocateUuid": "string",
  • "opportunityId": "string",
  • "referenceAdvocateScores": {
    },
  • "hasExternalId": true,
  • "referenceTypeUuid": "string",
  • "searchCriteria": "string",
  • "reportSize": 0
}