Get All User Profile Questions

URL: https://api.gradual-api.com/public-api/v1/userProfileQuestions

HTTP Method: GET

Content type: application/json

Tier: Medium

Returns the list of all user profile questions.

Response Example:

[
{
"id": "6553ce608b3f645e79d95034",
"title": "What is your area of expertise?",
"inUserProfileForm": true
},
{
"id": "6553ce608b3f645e79d95035",
"title": "Community active score",
"inUserProfileForm": false
}
]

Notes:

  • All user profile questions are returned. Value of inUserProfileForm indicates whether a question is included in users' profile form.
  • Use the question id with the Get User Profile Question Details endpoint to retrieve full question configuration including type, options, visibility, etc.
  • Question IDs can also be passed as extra parameters in the Update User Profile by Email endpoint to update a user's answers.

Get User Profile Question Details

URL: https://api.gradual-api.com/public-api/v1/userProfileQuestions/:questionId

HTTP Method: GET

Content type: application/json

Tier: Light

Path Parameters:

  • questionId, string, required, the question's ID

Response Example (Single Select):

{
"id": "6553ce608b3f645e79d95034",
"title": "What is your area of expertise?",
"subtitle": "Select the option that best describes your role",
"required": true,
"visibility": "Public",
"type": "Single Select",
"options": ["Engineering", "Product", "Design", "Marketing", "Sales"],
"withOtherOption": true
"inUserProfileForm": true,
"isUserEditable": true
}

Response Example (Multi Select):

{
"id": "6553ce608b3f645e79d95035",
"title": "Which topics are you interested in?",
"subtitle": "",
"required": false,
"visibility": "Public",
"type": "Multi Select",
"options": ["AI/ML", "Cloud", "Security", "DevOps", "Frontend"],
"withOtherOption": false,
"minNumOfSelection": 1,
"maxNumOfSelection": 3
"inUserProfileForm": true,
"isUserEditable": true
}

Response Example (Single Line Text):

{
"id": "6553ce608b3f645e79d95036",
"title": "Community active score",
"subtitle": "",
"required": false,
"visibility": "Secret",
"type": "Single Line Text",
"maxLength": 255
"inUserProfileForm": false,
"isUserEditable": false
}

Response Example (Paragraph):

{
"id": "6553ce608b3f645e79d95037",
"title": "Tell us about yourself",
"subtitle": "",
"required": false,
"visibility": "Public",
"type": "Paragraph",
"maxLength": 3000,
"minLength": 10
"inUserProfileForm": true,
"isUserEditable": true
}

Response Example (Location):

{
"id": "6553ce608b3f645e79d95038",
"title": "Where are you based?",
"subtitle": "",
"required": true,
"visibility": "Public",
"type": "Location",
"locationType": "city",
"inUserProfileForm": true,
"isUserEditable": false
}

Response Fields:

  • id, string, the question's unique identifier
  • title, string, the question text
  • subtitle, string, optional helper text displayed below the question
  • required, boolean, whether the question must be answered
  • isPrivate, boolean, deprecated, see visibility
  • visibility, string, visibility level (Public, MembersOnly, Secret)
  • type, string, question type (Single Line Text, Paragraph, Single Select, Multi Select, Location, URL)
  • options, array of strings, available choices (Single Select and Multi Select questions only)
  • withOtherOption, boolean, whether a free-text "Other" option is allowed (Single Select and Multi Select questions only)
  • minNumOfSelection, integer, minimum selections required (Multi Select questions only, omitted if not configured)
  • maxNumOfSelection, integer, maximum selections allowed (Multi Select questions only, omitted if not configured)
  • maxLength, integer, maximum character length (Single Line Text and Paragraph questions only)
  • minLength, integer, minimum character length (Paragraph questions only, omitted if not configured)
  • locationType, string, type of location expected (Location questions only)
  • inUserProfileForm, boolean, whether the question is included in users' profile form
  • isUserEditable, boolean, whether the question answer can be edited by user.

Notes:

  • Returns 404 if the question is not found.
  • The type field returns a human-readable label. Possible values: Single Line Text, Paragraph, Single Select, Multi Select, Location, URL.

Get a User by User ID

URL: https://api.gradual-api.com/public-api/v1/users/:userId

HTTP Method: GET

Content type: application/json

Tier: Light

Path Parameters:

  • userId, string, required, this is the unique identifier to find a user

Response Example:

{
"userId": "6553ce608b3f645e79d95034",
"userEmail": "[email protected]",
"userFirstName": "Jane",
"userLastName": "Doe",
"displayName": "Jane Doe",
"userTitle": "Software Engineer",
"userCompany": "Test Company",
"userAvatarUrl": "https://some-source.net/avatar-12345.png",
"userLinkedIn": "https://www.linkedin.com/in/janedoe",
"userLocation": "San Francisco, CA, United States",
"memberType": "Standard",
"approvalStatus": "approved",
"spaces": [
"Space 1",
"Space 2"
],
"questionnaire": {
"What is your area of expertise?": "Engineering",
"Which topics are you interested in?": "AI/ML;Cloud"
},
"signUpAt": "2024-06-12T08:21:16.388Z",
"lastLoginAt": "2024-06-14T16:07:13.786Z",
"onboardingAt": "2024-06-13T04:57:19.262Z",
"lifetimePoints": 150,
"remainingPoints": 75
}

Response Fields:

  • userId, string, the tenant user's unique identifier
  • userEmail, string, the user's email address
  • userFirstName, string, the user's first name
  • userLastName, string, optional, the user's last name (if available)
  • displayName, string, the user's full display name (typically First Name + Last Name)
  • userTitle, string, the user's job title/position
  • userCompany, string, the user's company name
  • userAvatarUrl, string, optional, URL of the user's profile picture (if available)
  • userLinkedIn, string, optional, the user's LinkedIn profile URL (if available)
  • userLocation, string, optional, the user's location (if available)
  • memberType, string, the user's membership type: Standard, Guest, or Limited Approval
  • approvalStatus, string, the user's approval status: approved, pending, or unapproved
  • spaces, array of strings, space names the user is assigned to (empty array if none)
  • questionnaire, object, map of profile question titles to the user's answers; multi-select answers are semicolon-delimited (empty object {} if no answers)
  • signUpAt, string, optional, ISO 8601 timestamp of when the user signed up
  • lastLoginAt, string, optional, ISO 8601 timestamp of the user's last login
  • onboardingAt, string, optional, ISO 8601 timestamp of when the user completed onboarding
  • lifetimePoints, number, optional, the user's total lifetime contribution points
  • remainingPoints, number, optional, the user's remaining redeemable points balance
  • externalId, string, optional, the user's external ID (if the user account is linked to an external source)
  • externalDisplayId, string, optional, the user's external display name (if the user account is linked to an external source)
  • externalProfileUrl, string, optional, URL to the user's external profile (if the user account is linked to an external source)

Get a User by Email

URL: https://api.gradual-api.com/public-api/v1/users

HTTP Method: GET

Content type: application/json

Tier: Medium

Query Parameters:

  • email, string, required, this is the unique identifier to find a user

Response: same as Get a User by User ID

Add a New User

URL: https://api.gradual-api.com/public-api/v1/users

HTTP Method: POST

Content type: application/json

Tier: Medium

Request Body Parameters:

  • email, string, required, this is the unique identifier to find and update user
  • firstName, string, required
  • lastName, string, same requirement as in user sign-up form
  • position, string, required
  • company, string, required
  • linkedInUrl, string, optional
  • pictureUrl, string, optional
  • spaces, array of strings, optional, spaces names to add user to

Request Body Example:

{
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"company": "Test Company",
"position": "Software Engineer",
"linkedInUrl": "",
"pictureUrl": ""
}

Response Example:

{
"userEmail": "[email protected]",
"userFirstName": "Jane",
"userLastName": "Doe",
"userTitle": "Software Engineer",
"userCompany": "Test Company",
"userLinkedIn": "",
"pictureUrl": "",
"userId": "6553ce608b3f645e79d95034",
"memberType": "Standard",
"approvalStatus": "approved",
"displayName": "Jane Doe",
"spaces": [
"Space 1",
"Space 2"
],
"questionnaire": {}
}

Update User Profile by Email

URL: https://api.gradual-api.com/public-api/v1/updateProfileByEmail

HTTP Method: POST

Content type: application/json

Tier: Medium

Request Body Parameters:

  • email, string, required, this is the unique identifier to find and update user
  • firstName, string, optional
  • lastName, string, optional
  • position, string, optional
  • company, string, optional
  • pictureUrl, string, optional
  • bio, string, optional
  • linkedInUrl, string, optional
  • memberType, string (one of "Standard", "Guest", or "Limited Approval"), optional, case-insensitive
  • approvalStatus, string (one of "approved", "pending", "unapproved"), optional, case-insensitive
  • [questionId], string, optional, the value should be the answer to the specific user profile question associated with the ID of questionId
    • if answer is an array containing multiple values, pass the answer value as a string separated by ; or , (using semicolon is recommended)
    • request may include multiple instances of this parameter in the same API call, each with a different questionId
    • to get question ids, use the endpoint Get All User Profile Questions

Request Example:

{
"email": "[email protected]",
"approvalStatus": "Approved",
"bio": "This is a test user.",
"6073c7a2a0295ca1b4d64c22": "Tech leader",
"6073c7a7a0295ca1b4d64c6b": "Mentor others; Help organize events"
}

Response Example:

{
"user": {
"id": "62978aa2f4cc421cf75f1359",
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"position": "Engineer",
"company": "Test Co.",
"pictureUrl": "https://abc.cloudfront.net/avatar/7856e6f6d40f.jpeg",
"bio": "This is a test user.",
"memberType": "Standard",
"approvalStatus": "Approved"
},
"updatedQuestionAnswers": {
"Current Level at your organization": "Tech leader",
"How do you want to contribute?": "Mentor others;Help organize events"
}
}

Delete a User

URL: https://api.gradual-api.com/public-api/v1/users

HTTP Method: DELETE

Content type: application/json

Tier: Medium

This endpoint queues a user for deletion. The operation is processed asynchronously — the user will be removed after the request is accepted.

Request Body Parameters:

  • email, string, optional, must be a valid email address
  • userId, string, optional, the user's ID

Either email or userId must be provided. If both are provided, email takes priority.

Request Body Example (by email):

{
"email": "[email protected]"
}

Request Body Example (by userId):

{
"userId": "6553ce608b3f645e79d95034"
}

Response Example:

{
"success": true,
"message": "User deletion request has been queued for processing"
}

Notes:

  • The deletion is processed asynchronously. A successful response (code 202) means the request has been accepted and queued, not that the user has been deleted yet.
  • Returns 404 if no user is found matching the provided email or userId.
  • Returns 400 if neither email nor userId is provided.
  • Archived users cannot be deleted through this endpoint.

Batch Create Users

URL: https://api.gradual-api.com/public-api/v1/users/batch

HTTP Method: POST

Content type: application/json

Tier: Heavy

This endpoint creates multiple users in a single request. The operation is processed asynchronously — you receive a job ID immediately and poll for results.

Request Body Parameters:

  • users, array, required, array of user objects (1–100 items)
  • users[].email, string, required, must be a valid email address
  • users[].firstName, string, required
  • users[].lastName, string, same requirement as in user sign-up form
  • users[].position, string, required
  • users[].company, string, required, minimum 2 characters
  • users[].pictureUrl, string, optional, must be a valid URL
  • users[].linkedInUrl, string, optional, must be a valid URL

Request Body Example:

{
"users": [
{
"email": "[email protected]",
"firstName": "Jane",
"lastName": "Doe",
"position": "Software Engineer",
"company": "Test Company",
"linkedInUrl": "",
"pictureUrl": ""
},
{
"email": "[email protected]",
"firstName": "John",
"lastName": "Smith",
"position": "Product Manager",
"company": "Test Company"
}
]
}

Response Example (202 Accepted):

{
"jobId": "6553ce608b3f645e79d95034",
"status": "pending"
}

Notes:

  • Duplicate emails within a single batch are rejected with a 400 error.
  • The maximum batch size is 100 users per request. For larger imports, submit multiple batches sequentially.
  • Each user in the batch goes through the same validation as the Add a New User endpoint. If any user fails validation, the entire batch is rejected before processing begins.
  • Poll the Get Batch Job Status endpoint to check the results after submitting.

Get Batch User Creation Job Status

URL: https://api.gradual-api.com/public-api/v1/users/batch/:jobId

HTTP Method: GET

Content type: application/json

Tier: Light

Path Parameters:

  • jobId, string, required, the job ID returned from the batch creation request

Response Example (job completed):

{
"jobId": "6553ce608b3f645e79d95034",
"status": "completed",
"results": [
{
"recordPosition": 0,
"email": "[email protected]",
"tenantUserId": "6553ce608b3f645e79d95035",
"status": "created"
},
{
"recordPosition": 1,
"email": "[email protected]",
"tenantUserId": "6553ce608b3f645e79d95036",
"status": "created"
}
]
}

Response Example (job with partial failures):

{
"jobId": "6553ce608b3f645e79d95034",
"status": "completed",
"results": [
{
"recordPosition": 0,
"email": "[email protected]",
"tenantUserId": "6553ce608b3f645e79d95035",
"status": "created"
},
{
"recordPosition": 1,
"email": "[email protected]",
"status": "failed",
"reason": "user already exists"
}
]
}

Job Statuses:

  • pending — job is queued and waiting to be processed
  • processing — job is currently being processed
  • completed — all users have been processed (check individual results for per-user status)
  • failed — job encountered a fatal error

Per-User Result Statuses:

  • created — user was successfully created
  • failed — user creation failed, see reason field for details

Notes:

  • Recommended polling interval is every 2–5 seconds.
  • A completed job does not mean all users were created successfully. Always check the individual results entries for per-user status.
  • The recordPosition field corresponds to the index of the user in the original users array (starting from 0).

Create a Contribution Log

URL: https://api.gradual-api.com/public-api/v1/contributionLogs

HTTP Method: POST

Content type: application/json

Tier: Medium

Request Body Parameters:

  • contributionName, string, required, name of the contribution (1–300 characters), must match an existing contribution
  • userEmail, string, required, email of the user to log the contribution for
  • contributedAt, string, required, ISO 8601 timestamp of when the contribution occurred
  • count, integer, optional, number of contributions to log (minimum 1, defaults to 1)
  • externalContributionId, string, optional, an external identifier for deduplication or tracking
  • notes, string, optional, additional notes (max 100 characters)

Request Body Example:

{
"contributionName": "Event Organizer",
"userEmail": "[email protected]",
"contributedAt": "2024-11-14T10:30:00.000Z",
"count": 1,
"externalContributionId": "ext-12345",
"notes": "Organized the Q4 Town Hall"
}

Response Example:

{
"contributionLogId": "6553ce608b3f645e79d95034",
"loggedAt": "2024-11-14T10:30:00.000Z",
"type": "manual",
"contribution": "Event Organizer",
"count": 1,
"occurredAt": "2024-11-14T10:30:00.000Z",
"loggedBy": "publicApi",
"notes": "Organized the Q4 Town Hall",
"contributorId": "6553ce608b3f645e79d95035",
"contributorName": "Jane Doe",
"contributorEmail": "[email protected]"
}

Notes:

  • The contributionName must exactly match an existing contribution configured in your community. If no matching contribution is found, the request will be rejected with a 400 error.
  • The user identified by userEmail must exist, otherwise the request will be rejected with a 400 error.
  • The contributedAt field must be a valid ISO 8601 date string.