API Reference - Users

Link: https://support.brilliantdirectories.com/support/solutions/articles/12000108047

← Back to API Reference | Getting Started

Users

Users (members) are the core of every Brilliant Directories website. This resource maps to the users_data database table. Every user belongs to a membership level (subscription type) and has a status code that controls their access to the site.

Model name in URL: user — DB table: users_data

The User Object

FieldTypeDescription
user_idintegerUnique user ID (primary key, read-only)
first_namestringUser's first name
last_namestringUser's last name
emailstringEmail address — must be unique across the site required on create
passwordstringPassword (plain text on create/update; stored as a hash). Write-only — never returned in any API response required on create
subscription_idintegerMembership level ID required on create
activeintegerAccount status: 1=Inactive, 2=Active, 3=Cancelled, 4=On Hold, 5=Past Due
companystringBusiness or company name
phone_numberstringPhone number
address1stringStreet address line 1
address2stringStreet address line 2
citystringCity
zip_codestringZIP or postal code
state_codestring2-letter state/province code (e.g. CA)
state_lnstringFull state/province name (e.g. California)
country_codestring2-letter country code (e.g. US)
country_lnstringFull country name (e.g. United States)
websitestringUser's website URL
twitterstringTwitter/X profile URL
youtubestringYouTube channel URL
facebookstringFacebook profile/page URL
linkedinstringLinkedIn profile URL
instagramstringInstagram profile URL
pintereststringPinterest profile URL
snapchatstringSnapchat handle
whatsappstringWhatsApp contact number
about_metextAbout Me biography (HTML allowed)
quotestringTagline or quote displayed on profile
experienceintegerYear experience began (e.g. 2015)
affiliationtextProfessional affiliations
awardstextAwards and achievements
credentialstextProfessional credentials or certifications
positionstringJob title or position
profession_idintegerIndustry/profession category ID
featuredinteger1 if user is featured, 0 otherwise
nationwideinteger1 if user serves clients nationwide
latnumberLatitude coordinate
lonnumberLongitude coordinate
signup_datestringDate user signed up (format: YYYYMMDDHHmmss)
last_loginstringDate/time of last login (format: YYYYMMDDHHmmss)
modtimetimestampLast modified timestamp (auto-updated)
filenamestringURL-friendly profile slug
parent_idintegerParent user ID for sub-accounts
verifiedinteger1 if email verified
blogtextBlog URL or blog content
no_geostringFlag to disable geocoding for this user
user_consenttextRecord of user consent (GDPR/privacy compliance)
search_descriptiontextCustom description displayed in search results
tokenstringLogin token (auto-generated). Not returned by default — available only through the opt-in flow described under Sensitive Fields & the Login Token below
cookiestringSession cookie token. Never returned in any API response
ref_codestringReferral code or signup source (e.g. Manually Added)
bitlystringBitly URL shortening flag or shortened URL
facebook_idstringFacebook account ID (for Facebook login integration)
google_idstringGoogle account ID (for Google login integration)
cvtextCurriculum vitae or resume content
work_experiencetextWork experience details
rep_matterstextBusiness hours or additional reputation information
gmapstringGoogle Maps embed URL or place ID
listing_typestringListing type classification. Enum — only supports 2 string values, either: "Individual" or "Company" (exact case). Misclassifying breaks site logic.

Special Update Parameters

ParameterTypeDescription
member_tag_actionintegerSet to 1 to add the specified tags, or 0 to remove them
member_tagsstringComma-separated numeric tag IDs (e.g. 1,2,3) to add or remove — use the tag ID, not the tag name. A tag name is silently ignored and the request still returns success. Each tag's ID is shown next to it in the Member Tags section of the admin.
credit_actionstringadd, deduct, or override credits
credit_amountnumberCredit amount for the credit action
images_actionstringremove_all, remove_cover_image, remove_logo_image, or remove_profile_image
servicesstringComma-separated list of sub-category names or IDs to assign to the member. For sub-sub nesting, use the format SubCategory=>SubSubCategory1,SubSubCategory2. By default, any names that don't already exist under the member's profession are ignored.
create_new_categoriesintegerSet to 1 to auto-create any category names in services that don't already exist under the member's profession. Requires a valid profession_id either on the request or already set on the member. New rows are inserted into list_services under the member's profession and linked to the member in rel_services.
delete_categoriesintegerSet to 1 to wipe all of the member's existing category assignments (all rel_services rows for the member) before any new services in the same request are applied. The category definitions in list_services are not affected. Combine with services= (and optionally create_new_categories=1) to replace the entire category list in a single call.
auto_geocodeinteger1 to automatically geocode the user's address
create_301_redirectintegerControls whether a 301 redirect is created when the update changes the member's profile URL. Defaults to on. Set to 0 to skip the redirect for that request only.
notifyintegerSet to 1 to send the member the account activation email when this update moves them into the Active status (active=2). Omitting the parameter, or sending 0, keeps the existing behavior of sending no email on a status change. The email is only sent when the update is an actual transition into Active — a member who is already Active receives nothing.
send_approval_emailintegerAlias of notify. Either parameter name can be used; they do the same thing.
Profession scope requirement: All category lookups and inserts are scoped by the member's profession_id. If the member's profession_id is 0 and no profession_id (or profession_name) is included on the request, the services parameter has no effective scope and no rel_services rows will be written for that member. Always set the top-level category first (or pass it alongside services) when adding sub-categories.

List Users

GET /api/v2/user/get

Returns a paginated list of users. Supports filtering and sorting via query parameters.

Example Request

Copy
curl -X GET "https://www.yourdomain.com/api/v2/user/get?limit=25" \
  -H "X-Api-Key: your-api-key-here"

Example Response

Copy
{
  "status": "success",
  "total": 84,
  "current_page": 1,
  "total_pages": 4,
  "next_page": "MipfKjI1",
  "message": [
    {
      "user_id": 1,
      "first_name": "Jane",
      "last_name": "Smith",
      "email": "jane@example.com",
      "company": "Acme Corp",
      "active": 2,
      "subscription_id": 1,
      "city": "Los Angeles",
      "state_code": "CA",
      "country_code": "US",
      "signup_date": "20240115143000"
    },
    ...
  ]
}

Retrieve a User

GET /api/v2/user/get/{user_id}

Returns a single user by their user_id.

Example Request

Copy
curl -X GET "https://www.yourdomain.com/api/v2/user/get/42" \
  -H "X-Api-Key: your-api-key-here"

Example Response

Copy
{
  "status": "success",
  "total": 1,
  "current_page": 1,
  "total_pages": 1,
  "message": [
    {
      "user_id": 42,
      "first_name": "John",
      "last_name": "Doe",
      "email": "john@example.com",
      "company": "Tech Solutions LLC",
      "active": 2,
      "subscription_id": 3,
      "phone_number": "555-867-5309",
      "city": "San Francisco",
      "state_code": "CA",
      "country_code": "US",
      "website": "https://www.techsolutions.com",
      "signup_date": "20230901090000"
    }
  ]
}

Sensitive Fields & the Login Token

Every /api/v2/user/* response omits the password, token, and cookie fields. password and cookie are never returned under any circumstances. The member's login token can be returned on an opt-in, per-key basis — all three of the following conditions must hold at the same time:

  • The request is a single-record retrieve (GET /api/v2/user/get/{user_id}). List and paginated requests never include the token.
  • The request sends include_user_token=1.
  • The API key has been granted the Include User Token permission, found in the Sensitive Data section of the key's API Permissions (Developer Hub » API Keys). This permission is off by default on every key, and the bulk enable-all control deliberately skips it — it can only be switched on individually.
Treat the login token like a password: POST /api/v2/user/login accepts the token in place of the member's password, and on sites with the enable_login_token_link Advanced Setting enabled it logs the member in directly via /login/token/{token}. Every token retrieval is audit-logged with the API key ID and member ID.

Example Request (with login token)

Copy
curl -X GET "https://www.yourdomain.com/api/v2/user/get/35?include_user_token=1" \
  -H "X-Api-Key: your-api-key-here"

Create a User

POST /api/v2/user/create

Creates a new user. The email, password, and subscription_id fields are required.

Required Fields

ParameterTypeDescription
emailstringRequired
passwordstringRequired
subscription_idintegerRequired — membership level ID

Example Request

Copy
curl -X POST "https://www.yourdomain.com/api/v2/user/create" \
  -H "X-Api-Key: your-api-key-here" \
  -d "email=jane@example.com" \
  -d "password=SecurePass123" \
  -d "subscription_id=1" \
  -d "first_name=Jane" \
  -d "last_name=Smith" \
  -d "company=Acme+Corp" \
  -d "phone_number=555-555-1234" \
  -d "city=Los+Angeles" \
  -d "state_code=CA" \
  -d "country_code=US"

Example Response

Copy
{
  "status": "success",
  "message": {
    "user_id": 101,
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane@example.com",
    "company": "Acme Corp",
    "active": 1,
    "subscription_id": 1
  }
}

Subscription Start Date & Billing Cycle

A member can be created with a subscription that is already established, rather than one that necessarily begins on the day the record is created. Sending subscription_start_date and billing_cycle together on the create call writes the member's billing record with the supplied start date, a next due date one full billing cycle later, and the requested cycle. Carrying members over from another platform with their original renewal dates intact is one common reason to use this, but the two parameters apply to any member whose subscription needs a specific start date. Both are optional, and omitting them leaves the existing behavior unchanged: the subscription starts on the day the member is created, on the plan's default cycle.

ParameterTypeDescription
subscription_start_datestringDate the subscription begins. Accepted formats are YYYY-MM-DD (2024-06-15), YYYYMMDD (20240615), and the date format the website itself is configured to display, such as MM/DD/YYYY or DD/MM/YYYY.
billing_cyclestringRenewal interval for the subscription. One of monthly, quarterly, semiannually, annually, biennially, or triennially. Matched without regard to capitalization.
Both values are validated before the member is created, and a failure returns an error instead of creating anything.
Sending one parameter without the other is rejected.
Only paid membership plans are supported. Free and claim plans are rejected.
The plan must charge more than zero for the requested interval.
The date must be a real calendar date, no more than one billing cycle in the past and no more than ten years in the future.

Not every website offers all six intervals. Membership plans store a separate price for each one, and plans that have no price set for the requested interval reject it, so checking the plan's pricing before choosing a cycle avoids the error. Older websites commonly carry only a monthly and a yearly price, which means the quarterly, semiannual, biennial and triennial values are rejected on those sites.

Create only. Both parameters are read on POST /api/v2/user/create and nowhere else. PUT /api/v2/user/update accepts them without returning an error but ignores them entirely, including values that would have been rejected on create. Neither value is stored on the member record itself, so neither is returned by GET /api/v2/user/get. An existing member's billing dates are changed through the admin panel's billing tools.

Example Request (with subscription dates)

Copy
curl -X POST "https://www.yourdomain.com/api/v2/user/create" \
  -H "X-Api-Key: your-api-key-here" \
  -d "email=jane@example.com" \
  -d "password=SecurePass123" \
  -d "subscription_id=1" \
  -d "first_name=Jane" \
  -d "last_name=Smith" \
  -d "subscription_start_date=2024-06-15" \
  -d "billing_cycle=annually"

Example Error Response

Copy
{
  "status": "error",
  "message": "subscription_start_date cannot be more than 1 billing cycle (monthly) in the past"
}

Update a User

PUT /api/v2/user/update

Updates an existing user. The user_id is required in the request body. Only include the fields you want to change.

Profile URL changes create a 301 redirect.

When a member's profile URL is changed through the API, a 301 redirect is now created automatically from the old URL to the new one. This matches the behavior already used when a profile URL is changed through the admin panel, helping ensure that previously shared or indexed profile links continue to work instead of returning a 404 error.

The redirect is created by default when using /api/v2/user/update.
To skip the redirect for a specific request, create_301_redirect=0 can be included. This option applies only to that request and does not change the default behavior.

Activating a member is silent unless the email is requested.
Setting active=2 through the API sends no email by default, so existing integrations are unaffected. Adding notify=1 (or send_approval_email=1) to the same request sends the member the account activation email, which is the same notice the admin panel sends when a member is approved by hand. The site's member activation template is used, falling back to the signup email template configured on the member's membership plan. If neither template exists on the site, the member is still activated and a note is recorded on the member record explaining that no email could be sent.

Example Request

Copy
curl -X PUT "https://www.yourdomain.com/api/v2/user/update" \
  -H "X-Api-Key: your-api-key-here" \
  -d "user_id=101" \
  -d "company=New+Company+Name" \
  -d "active=2" \
  -d "phone_number=555-999-8888"

Example Response

Copy
{
  "status": "success",
  "message": {
    "user_id": 101,
    "first_name": "Jane",
    "last_name": "Smith",
    "company": "New Company Name",
    "active": 2,
    "phone_number": "555-999-8888"
  }
}

Managing Member Categories

Member categories (sub-categories under a profession) are assigned through the same /api/v2/user/update endpoint using the services parameter together with create_new_categories and delete_categories. Categories themselves live in list_services and the member-to-category relations live in rel_services. Both are scoped by the member's profession_id, so make sure the member has a valid top-level profession set before managing their sub-categories.

Add categories to a member (auto-creating missing ones)

Sends three category names. Any name that already exists under the member's profession is linked to the member; any name that doesn't yet exist is first inserted into list_services under the member's profession and then linked.

Copy
curl -X PUT "https://www.yourdomain.com/api/v2/user/update" \
  -H "X-Api-Key: your-api-key-here" \
  -d "user_id=35" \
  -d "services=Appliances+%26+Repair,Home+Cleaning,Handyman+Services" \
  -d "create_new_categories=1"

Clear all of a member's categories

Wipes every rel_services row for the member. The underlying categories in list_services are left in place.

Copy
curl -X PUT "https://www.yourdomain.com/api/v2/user/update" \
  -H "X-Api-Key: your-api-key-here" \
  -d "user_id=35" \
  -d "delete_categories=1"

Replace a member's entire category list in one call

Combines delete_categories, services, and create_new_categories to clear the existing assignments and reassign a new set atomically. This mirrors the "delete all and re-add" workflow available in the admin UI.

Copy
curl -X PUT "https://www.yourdomain.com/api/v2/user/update" \
  -H "X-Api-Key: your-api-key-here" \
  -d "user_id=35" \
  -d "delete_categories=1" \
  -d "services=Plumbing,Electrical,HVAC" \
  -d "create_new_categories=1"

Read a member's categories as a nested tree

GET /api/v2/user/categories/{user_id} returns the member's assigned top-level category with their assigned sub- and sub-sub-categories nested inside — the read-side companion to the services parameter above. This is a standard endpoint, allowed by default for every API key.

Copy
curl -X GET "https://www.yourdomain.com/api/v2/user/categories/35" \
  -H "X-Api-Key: your-api-key-here"
Copy
{
  "status": "success",
  "message": {
    "profession_id": 1,
    "name": "Home Services",
    "filename": "home-services",
    "sub_categories": [
      {
        "service_id": 1,
        "name": "Plumbing",
        "filename": "plumbing",
        "profession_id": 1,
        "master_id": 0,
        "sub_sub_categories": []
      }
    ]
  }
}
Need finer control? For managing individual category definitions (create a new sub or sub-sub category, delete a category record) use the list_services endpoints. For managing individual member-to-category links by rel_id without touching the whole list, use the rel_services endpoints.

Delete a User

DELETE /api/v2/user/delete

Permanently deletes a user and all associated data. The user_id is required. Set delete_images to 1 to also remove the user's uploaded image files.

Example Request

Copy
curl -X DELETE "https://www.yourdomain.com/api/v2/user/delete" \
  -H "X-Api-Key: your-api-key-here" \
  -d "user_id=101" \
  -d "delete_images=1"

Example Response

Copy
{
  "status": "success",
  "message": "user record was deleted"
}

Search Users

POST /api/v2/user/search

Performs a full member directory search with keyword, category, and location filtering. This endpoint mirrors the front-end member search functionality.

Search Parameters

ParameterTypeDescription
qstringKeyword to search across member data
pidintegerTop-level category ID to filter by
tidintegerSub-level category ID to filter by
ttidintegerSub-sub-level category ID to filter by
addressstringLocation to search near (e.g. Los Angeles, CA)
sortstringSort order: reviews, name ASC, name DESC, last_name_asc, last_name_desc
pageintegerPage number
limitintegerResults per page
dynamicintegerSet to 1 to use Dynamic Category Filter search mode
output_typestringarray (default) or html

Example Request

Copy
curl -X POST "https://www.yourdomain.com/api/v2/user/search" \
  -H "X-Api-Key: your-api-key-here" \
  -d "q=plumber" \
  -d "address=Chicago%2C+IL" \
  -d "limit=10"

User Login

POST /api/v2/user/login

Validates a user's email and password. Returns a success or error status indicating whether the credentials are valid. This endpoint does not return user profile data — use GET /api/v2/user/get to retrieve user details after confirming credentials.

Example Request

Copy
curl -X POST "https://www.yourdomain.com/api/v2/user/login" \
  -H "X-Api-Key: your-api-key-here" \
  -d "email=jane@example.com" \
  -d "password=SecurePass123"

Example Response

Copy
{
  "status": "success",
  "message": "credentials are valid"
}

User Transactions

POST /api/v2/user/transactions

Returns billing transactions for a specific user. Pass the user's user_id as a POST body parameter.

Example Request

Copy
curl -X POST "https://www.yourdomain.com/api/v2/user/transactions" \
  -H "X-Api-Key: your-api-key-here" \
  -d "user_id=42"

User Subscriptions

POST /api/v2/user/subscriptions

Returns the subscription/membership history for a specific user. Pass the user's user_id as a POST body parameter.

Example Request

Copy
curl -X POST "https://www.yourdomain.com/api/v2/user/subscriptions" \
  -H "X-Api-Key: your-api-key-here" \
  -d "user_id=42"

Send an Email Template to Members

POST /api/v2/user/send-template

Renders an existing email template and sends it to one or more members of the site, on demand. The email goes out at the moment the call is made rather than waiting on an automated site event, which makes this the endpoint to use for approval notices, requests for more information, and any other member-facing email an integration needs to trigger itself.

API keys created before this endpoint existed do not have it enabled.
The permission is granted automatically only on newly created keys. An older key receives a 403 response until /api/v2/user/send-template is switched on under Developer Hub → the API key → Permissions. The change takes effect immediately and the key does not need to be regenerated.

Parameters

ParameterTypeDescription
user_id requiredstringThe recipient. Either a single member ID (EG 101) or a comma-separated list of up to 100 IDs (EG 101,102,103,104). Duplicate IDs are ignored. Every ID must belong to the site the API key was issued for.
template_namestringThe email_name of the template to send, and the preferred way to choose one. The name resolves to the site's own template of that name when the site has one, and otherwise to the platform default template of that name — the same local-then-default rule used for widget, form, and menu names.
email_template_idstringAn alternative to template_name. A numeric value is read as the email_id of a template belonging to the site. A non-numeric value is read as a template name and resolves exactly as template_name does. One of the two parameters is required.
Which templates can be sent.
Templates in the My Saved Templates, Customer Service, Billing, System, and Lead categories can be sent to an individual member. Newsletter templates cannot — those are built for list sends rather than for a single recipient. A request naming a template outside the sendable categories is rejected with Email template not found and no email is sent.
Sending is limited to the API key's own site.
A member ID that does not belong to the site is skipped and reported as a failed recipient, as is a member with no valid email address. There is never a cross-site send and never a fallback recipient. Every email that is sent is also recorded as a note on the member record, so the send history is visible in the admin panel.

Example Request (single member)

Copy
curl -X POST "https://www.yourdomain.com/api/v2/user/send-template" \
  -H "X-Api-Key: your-api-key-here" \
  -d "user_id=101" \
  -d "template_name=account-activated"

Example Response (single member)

A call naming one member returns the flat status and message shape.

Copy
{
  "status": "success",
  "message": "Email sent to member"
}

Example Request (multiple members)

Copy
curl -X POST "https://www.yourdomain.com/api/v2/user/send-template" \
  -H "X-Api-Key: your-api-key-here" \
  -d "user_id=101,102,103,104" \
  -d "template_name=account-activated"

Example Response (multiple members)

A comma-separated user_id returns a per-member breakdown under data, with one entry per requested ID in request order. The overall status is success when at least one member was sent to, and error when none were.

Copy
{
  "status": "success",
  "message": "Email sent to 3 of 4 member(s)",
  "data": {
    "sent": 3,
    "failed": 1,
    "results": [
      { "user_id": 101, "status": "success", "message": "Email sent to member" },
      { "user_id": 102, "status": "success", "message": "Email sent to member" },
      { "user_id": 103, "status": "success", "message": "Email sent to member" },
      { "user_id": 104, "status": "error", "message": "Member not found on this site" }
    ]
  }
}

Error Messages

MessageCause
user_id is requiredNo user_id was supplied, or none of the supplied values were valid member IDs.
email_template_id or template_name is requiredNeither template selector was supplied.
Too many user_ids (max 100)More than 100 member IDs were listed in a single call. Split the list across several calls.
Email template not foundNo template matched the name or ID on this site or among the platform defaults, or the template that matched is in a category that cannot be sent to an individual member. No email is sent in either case.
Member not found on this siteReturned per recipient. The member ID does not belong to the site the API key was issued for.
Member does not have a valid email addressReturned per recipient. The member record has no usable email address.