Summary and recommendation
Less Annoying CRM exposes a user management API at a single flat endpoint (`https://api.lessannoyingcrm.com`) using a `Function` query parameter pattern rather than discrete REST resource paths. All operations - including CreateUser, EditUser, DeleteUser, and GetUsers - are issued as HTTP GET requests with credentials and parameters passed as query strings.
There is no REST/JSON body POST interface for user operations.
Authentication is static: every request requires a `UserCode` and `APIToken` pair. There is no OAuth 2.0, no token rotation, and no scoped credential model. Only admin-level tokens can access user-management functions; non-admin tokens are rejected at the API layer.
For teams building identity graph pipelines or connecting LACRM to a broader IT/identity integration layer - such as an MCP server with 60+ deep IT/identity integrations - the absence of SCIM, webhooks, and rate-limit headers are the primary architectural constraints to plan around.
API quick reference
| Has user API | Yes |
| Auth method | API key passed as query parameter or HTTP header (UserCode + APIToken) |
| Base URL | Official docs |
| SCIM available | No |
| SCIM plan required | N/A |
Authentication
Auth method: API key passed as query parameter or HTTP header (UserCode + APIToken)
Setup steps
- Log in to Less Annoying CRM as an administrator.
- Navigate to Settings > API.
- Generate or copy your API token.
- Note your UserCode (visible on the same page).
- Include both UserCode and APIToken in every API request as query parameters or headers.
User object / data model
| Field | Type | Description | On create | On update | Notes |
|---|---|---|---|---|---|
| UserId | string | Unique identifier for the user within the account | system-assigned | immutable | Used to reference a specific user in API calls |
| Name | string | Full display name of the user | required | optional | |
| EmailAddress | string | Login email address for the user | required | optional | Must be unique within the account |
| IsAdmin | boolean | Whether the user has administrator privileges | optional | optional | Only admins can manage other users via the API |
| DateCreated | datetime | Timestamp when the user was created | system-assigned | immutable | ISO 8601 format |
Core endpoints
List Users
- Method: GET
- URL:
https://api.lessannoyingcrm.com?Function=GetUsers&UserCode={UserCode}&APIToken={APIToken} - Watch out for: Only account administrators can call user-management functions. Non-admin API tokens will receive an error.
Request example
GET https://api.lessannoyingcrm.com?Function=GetUsers&UserCode=ABC123&APIToken=xyz789
Response example
{
"Result": [
{"UserId":"u1","Name":"Jane Doe","EmailAddress":"jane@example.com","IsAdmin":true}
]
}
Get Single User
- Method: GET
- URL:
https://api.lessannoyingcrm.com?Function=GetUser&UserCode={UserCode}&APIToken={APIToken}&UserId={UserId} - Watch out for: UserId must belong to the same account as the authenticating UserCode.
Request example
GET https://api.lessannoyingcrm.com?Function=GetUser&UserCode=ABC123&APIToken=xyz789&UserId=u1
Response example
{
"Result": {
"UserId":"u1",
"Name":"Jane Doe",
"EmailAddress":"jane@example.com",
"IsAdmin":true
}
}
Create User
- Method: GET
- URL:
https://api.lessannoyingcrm.com?Function=CreateUser&UserCode={UserCode}&APIToken={APIToken}&Name={Name}&EmailAddress={EmailAddress} - Watch out for: Creating a user counts against your billing seat count immediately. Less Annoying CRM charges $15/user/month per seat.
Request example
GET https://api.lessannoyingcrm.com?Function=CreateUser&UserCode=ABC123&APIToken=xyz789&Name=John+Smith&EmailAddress=john@example.com
Response example
{
"Result": {
"UserId": "u2"
}
}
Edit User
- Method: GET
- URL:
https://api.lessannoyingcrm.com?Function=EditUser&UserCode={UserCode}&APIToken={APIToken}&UserId={UserId}&Name={Name} - Watch out for: Only fields explicitly passed are updated; omitted fields retain their current values.
Request example
GET https://api.lessannoyingcrm.com?Function=EditUser&UserCode=ABC123&APIToken=xyz789&UserId=u2&Name=John+A.+Smith
Response example
{
"Result": "Success"
}
Delete User
- Method: GET
- URL:
https://api.lessannoyingcrm.com?Function=DeleteUser&UserCode={UserCode}&APIToken={APIToken}&UserId={UserId} - Watch out for: Deleting a user is irreversible via the API. All data owned by that user may be reassigned or lost depending on account settings.
Request example
GET https://api.lessannoyingcrm.com?Function=DeleteUser&UserCode=ABC123&APIToken=xyz789&UserId=u2
Response example
{
"Result": "Success"
}
Rate limits, pagination, and events
- Rate limits: Less Annoying CRM does not publish explicit rate limit tiers. The API documentation notes that excessive requests may be throttled, but no specific numeric limits are documented officially.
- Rate-limit headers: No
- Retry-After header: No
- Rate-limit notes: No documented rate limit headers or retry-after semantics. Avoid high-frequency polling; use reasonable request intervals.
- Pagination method: offset
- Default page size: 0
- Max page size: 0
- Pagination pointer: Page
| Plan | Limit | Concurrent |
|---|---|---|
| All plans (flat rate) | Not publicly documented | 0 |
- Webhooks available: No
- Webhook notes: Less Annoying CRM does not offer native webhook support as of the current documentation. There is no event-subscription mechanism for user lifecycle events.
- Alternative event strategy: Poll the GetUsers endpoint periodically to detect changes in user roster.
SCIM API status
- SCIM available: No
- SCIM version: Not documented
- Plan required: N/A
- Endpoint: Not documented
Limitations:
- No SCIM 1.1 or 2.0 support documented.
- No SAML or OIDC SSO, so automated provisioning via IdP is not natively supported.
- Okta integration exists but is limited; does not include SCIM-based provisioning/deprovisioning.
Common scenarios
Provisioning a new user requires a GET to Function=CreateUser with Name and EmailAddress. The returned UserId should be captured immediately and stored in your identity graph to enable future edits or deprovisioning without a lookup round-trip. If admin rights are needed, a follow-up call to Function=EditUser with IsAdmin=true is required - there is no single-call provisioning with role assignment.
Deprovisioning requires calling Function=GetUsers to resolve the UserId if not already stored, followed by Function=DeleteUser. Deletion is irreversible via the API; data reassignment must be handled before the delete call, as there is no undo mechanism and no deactivate-then-delete workflow.
Directory sync must be polling-based. Call Function=GetUsers on a schedule, diff against your authoritative source (HR system or IdP), and issue CreateUser or DeleteUser calls for delta records. No webhooks exist, so there is no event-driven trigger available for user lifecycle changes.
Provision a new employee
- Authenticate with admin UserCode and APIToken.
- Call Function=CreateUser with Name and EmailAddress parameters.
- Capture the returned UserId for future reference.
- Optionally call Function=EditUser to set IsAdmin if the user needs admin rights.
Watch out for: Each created user immediately adds a $15/month seat to the account bill. Confirm billing authorization before bulk provisioning.
Deprovision a departing employee
- Call Function=GetUsers to retrieve the current user list and locate the target UserId.
- Optionally reassign or export the user's CRM data via contact/pipeline endpoints before deletion.
- Call Function=DeleteUser with the target UserId.
- Verify removal by calling Function=GetUsers again.
Watch out for: Deletion is irreversible via the API. Ensure data reassignment is handled before deleting the user.
Sync user roster with an external directory
- Periodically call Function=GetUsers to retrieve the current LACRM user list.
- Compare against your authoritative directory (e.g., HR system or IdP).
- Call Function=CreateUser for net-new users found in the directory but not in LACRM.
- Call Function=DeleteUser for users present in LACRM but no longer in the directory.
- Log all changes for audit purposes.
Watch out for: No webhooks or SCIM mean this sync must be polling-based. There is no real-time event trigger available.
Why building this yourself is a trap
The most significant architectural caveat is that every CreateUser and DeleteUser call has an immediate billing side effect - seats are added or removed from the account bill in real time. Bulk provisioning scripts must include explicit billing authorization gates; there is no dry-run or staging mode.
Rate limits are undocumented. No rate-limit headers are returned, and there is no Retry-After semantic. Aggressive polling or bulk operations should implement exponential backoff on error responses, as throttling behavior is not specified.
The static API key model (UserCode + APIToken) means credential rotation requires manual intervention and re-distribution to any consuming service.
Combined with the absence of SCIM and SAML, this makes LACRM a leaf node in any IdP-driven identity graph - changes in the authoritative directory will never propagate automatically and must be driven by your own sync layer.
Automate Less Annoying CRM workflows without one-off scripts
Stitchflow builds and maintains end-to-end IT automation across your SaaS stack, including apps without APIs. Built for exactly how your company works, with human approvals where they matter.