Audience: Developers, solutions engineers, and technical admins integrating PlusPlus with internal tools, automations, or AI agents.
TL;DR:
Use GraphQL to query exactly the data you need (users, content, relationships).
Use the Agent API (REST) to take action (assign/enroll, mark progress, add feedback, check in to events, etc.).
What is the Agent API?
The Agent API is a REST interface for performing business actions in PlusPlus, assigning content, enrolling users, marking progress/completion, recording feedback, and more. It’s designed to be simple and idempotent where appropriate, so external tools or AI agents can safely call it.
Why split GraphQL and REST?
GraphQL excels at queries: you shape the response, traverse relationships, and paginate consistently.
REST (Agent API) excels at actions: you kick off a process and get back a success/failure payload.
Use them together:
GraphQL → find targets (e.g., new hires, a specific track).
Agent API → perform the action (assign/enroll, progress update, feedback, etc.).
Base URL & Versioning
Base URL:
https://<your-tenant>.plusplus.app/public_apiVersioning:
/v1/(backward-incompatible changes will use/v2/, etc.)
Replace <your-tenant> with your actual tenant subdomain. If you don’t know it, contact Support.
Authentication
Auth Type: Bearer token (HTTP header)
Agent API Header:
Authorization: <your-token-here>GraphQL Header:
Authorization: <your-token-here>Who can get a token? Admin users (today). A dedicated service-account model is planned; until then, generate tokens as an admin and manage/revoke as needed.
Security tip: Store tokens in a secrets manager (e.g., Vault, AWS Secrets Manager). Don’t hardcode tokens.
Quick Start
1. Prerequisites
Admin access to PlusPlus (to generate an API token)
Your tenant subdomain
curl / Postman or your preferred HTTP client
2. Make a test call
curl -X GET \ "https://<your-tenant>.plusplus.app/public_api/v1/health" \ -H "Authorization: <TOKEN>"
200 OK means the token and base URL are working.
Available Endpoints (v1)
The following endpoints are available in the current Agent API preview:
Events
1. Can Enroll
POST /public_api/v1/can_enroll
Check if a user can be enrolled in one or more events.
Query Parameters:
user_id(integer, required)method(string, optional:onlineorin-person, defaultin-person)accept_waitlist(boolean, optional, defaultfalse)
Body:
{ "event_ids": [7834, 120] }Response:
{ "results": [ {"event_id": 7834, "status": "Enrolled"}, {"event_id": 120, "status": "Failed"} ] }2. Enroll
POST /public_api/v1/enroll
Enroll a user in a specific event.
Query Parameters:
user_id(integer, required)event_id(integer, required)method(string, optional:onlineorin-person, defaultin-person)accept_waitlist(boolean, optional, defaultfalse)
Response:
{ "event_id": 1, "status": "Enrolled" }
Content Items
Assign
POST /public_api/v1/assign
Assign a user to a content item. Optionally include a due date.
Query Parameters:
user_id(integer, required)content_item_id(integer, required)due_date(string, optional, formatYYYY-MM-DD)
Response:
{ "content_item_id": 1, "assignment_id": 874, "status": "Created" }Status values: Created, Exists, Failed
Error Handling
401 Unauthorized: Invalid/missing token
400 Bad Request: Validation or input error
422 Validation Failed: Field-level errors
429 Too Many Requests: Backoff and retry
Error shape example:
{ "message": "An error has occurred." }How GraphQL & Agent API Work Together
See the GraphQL Getting Started Guide for full details.
Pairing Pattern
Use GraphQL to find IDs: Query users, events, or content. Example:
query NewHires($since: DateTime!) {
users(filter: { hiredAtGte: $since }) {
edges {
node { pk email } }
pageInfo { endCursor }
}
}GraphQL uses cursor-based pagination (
pageInfo.endCursor→after).IDs often appear as
pkin GraphQL results.
Use Agent API to act:
# Assign user to content curl -X POST \ "https://<tenant>.plusplus.app/public_api/v1/assign?user_id=123&content_item_id=456" \ -H "Authorization: <TOKEN>"
Common Recipes
Check if a user can enroll in events, then enroll:
query EventsByName($name: String!) {
events(first: 10, name: $name) {
edges { node { pk name } }
pageInfo { endCursor }
}
}# Can Enroll curl -X POST \ "https://<tenant>.plusplus.app/public_api/v1/can_enroll?user_id=123&method=online&accept_waitlist=true" \ -H "Authorization: <TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "event_ids": [7834, 120] }' # Enroll curl -X POST \ "https://<tenant>.plusplus.app/public_api/v1/enroll?user_id=123&event_id=7834&method=online&accept_waitlist=true" \ -H "Authorization: <TOKEN>"Assign content by name:
query ContentByName($name: String!) { content_items(first: 1, name: $name) { edges { node { pk name } } } }curl -X POST \ "https://<tenant>.plusplus.app/public_api/v1/assign?user_id=123&content_item_id=456&due_date=2025-10-31" \ -H "Authorization: <TOKEN>"
Security Best Practices
Use least-privilege tokens; rotate regularly
Store secrets securely (never embed in client-side code)
Monitor and revoke tokens when employees leave
Notes
The API is in preview mode. Stability and implementation details may change.
Service accounts and additional endpoints (progress updates, sentiment feedback) are planned.
Need Help?
If you have questions:
Open the in-app Support launcher, or
Email us at [email protected]
