Read organization analytics users

Read one page of an organization's analytics roster: one row per current member, with
what that member contributed over a period.

The roster is computed off the request path, like the metrics it is drawn from. A
roster that is not in the cache answers 202 Accepted with Retry-After, an empty
data array and users under meta.pending. Re-issue the identical request after
that many seconds. An empty page on a 202 means "not ready yet", never "no members".

Rows describe the organization's current roster. A member who has since left is absent,
even from a range that predates their departure. Owners are reported as admin — this
view has no separate owner role.

The endpoint is opt-in while in pilot: it answers only for organizations Padlet has
enrolled, and enrollment is granted on the organization's owner. Ask Padlet support to
enroll an organization.

Requires an API key belonging to an admin of the organization (a teacher, for a classroom).
Organization not enrolled, unknown id, or no access — every denial answers the same 404.

🚧

Opt-in while the endpoint is in pilot

This endpoint only answers for organizations Padlet has enrolled. Enrollment is granted on the organization's owner. Being an admin is not enough. Email [email protected] to ask for enrollment. Until then every call answers 404, the same response an unknown organization gets.

📘

API key

You will need to include your API key found here.

Please include the key in your header. {"X-API-KEY": <api_key>}

The key must belong to an admin of the organization, or a teacher for a classroom.

🔄

A 202 means poll, not fail

The roster is computed off the request path. When it is not cached, the response is 202 Accepted with a Retry-After header. The data array is empty. users appears under meta.pending. Re-issue the identical request after that many seconds.

An empty page on a 202 means the roster is not ready. It never means the organization has no members.

Reads one page of an organization's analytics roster. Each row is one current member, with what that member contributed over a period.

It is not a breakdown of memberCount. That metric counts members who joined on or before to, while this roster lists every current member whenever they joined, so meta.totalCount and memberCount can disagree.

Query parameters

ParameterNotes
from, toYYYY-MM, inclusive. The range counts both endpoints and may span at most 24 of them, so to can be no more than 23 months after from. Send both or neither. Omitting both reads the organization's current billing term, or all time if it has none
status[]active or inactive. Repeatable. Listing both is the same as omitting it
userType[]admin, maker, teacher, student, contributor, guest. Repeatable
qCase-insensitive substring match on name or email
sortname (default), email, userType, signupDate, lastActivityDate, padlets, posts, comments, reactions
orderasc (default) or desc
page1-based, default 1
perPageDefault 25, maximum 100

Repeatable parameters take PHP-style brackets: status[]=active&status[]=inactive. A single value can be sent without them.

from cannot precede January of five years ago, and to cannot be later than the current month. A range inside the 24-month cap but outside that window is still a 400.

Nothing is clamped. A perPage above 100, a zero or negative page, and an unknown sort, order, status or userType value are all a 400. (page - 1) * perPage may not exceed 1,000,000.

Any role in the list is accepted for any organization. Asking a classroom for maker returns no rows rather than an error.

Rows with no value for the sort column sort to the start of an ascending page and the end of a descending one. A sort=lastActivityDate scan therefore reaches members who never contributed either first or last, depending on order.

Row attributes

AttributeNotes
nameDisplay name, falling back to the username when it is blank
usernamePadlet username. Can be null
emailCan be null
userTypeThe member's role. Owners are reported as admin
activeWhether the member contributed anything in the range
signupDateUTC date the member signed up for Padlet, not the date they joined this organization
lastActivityDateTheir most recent activity in this organization, all time. Not scoped to the range. See below
padletsPadlets created in the range
postsPosts written in the range
commentsComments written in the range
reactionsReactions given in the range

The id of each row is the member's user hashid.

What the roster covers

Rows are the organization's current roster. A member who has since left is absent, even from a range that ends before they left.

The four counts and active are scoped to the range. lastActivityDate is not. It is the member's most recent activity in this organization, whenever it happened. That means it can fall outside the range in either direction.

lastActivityDate also counts time spent on a padlet. The four counts do not. A member who is inactive for the range can therefore still carry a date.

lastActivityDate is null only when the member has no recorded activity in the organization at all.

There is no owner value for userType. The roster reports owners as admin. Filtering userType[]=admin therefore returns admins and the owner together. There is no way to ask for the owner alone.

active means the member created a padlet, post, comment or reaction in the range. Reading or viewing does not count, so a member who only opened padlets is inactive.

Meta

FieldNotes
statusready, pending while the roster is being computed, or failed
dateRangeThe range the counts cover, to the day
pageThe page served
perPageRows per page
totalCountRows matching the filters across all pages, not the size of this page
totalPagesceil(totalCount / perPage)
pending["users"] on a 202, alongside retryAfter
errors["users"] when the roster failed. data is empty. Read it as an error, never as no members

A failed roster answers 200, not a 5xx. Check meta.status before reading data.

Errors

CodeMeaning
400An unknown sort, order, status or userType value, a non-positive page or perPage, a perPage above 100, an offset past 1,000,000 rows, or a malformed or too-wide range
401Missing or revoked API key
404The organization does not exist, is not enrolled, or your key has no analytics access to it. All three get the same response
406The Accept header named something else. Send application/vnd.api+json, or omit it
429More than 60 requests in an hour for this API key and organization. This endpoint has its own allowance, separate from the metrics endpoint. Retry-After gives the wait in seconds

Example

curl "https://api.padlet.dev/v1/organizations/$ORG_ID/analytics/users?from=2026-01&to=2026-03&status[]=active&sort=posts&order=desc&perPage=2" \
  -H "X-API-KEY: $PADLET_API_KEY"
{
  "data": [
    {
      "id": "user_abcd1234efgh5678",
      "type": "organizationAnalyticsUser",
      "attributes": {
        "name": "Ada Lovelace",
        "username": "ada",
        "email": "[email protected]",
        "userType": "teacher",
        "active": true,
        "signupDate": "2025-09-14",
        "lastActivityDate": "2026-03-02",
        "padlets": 4,
        "posts": 37,
        "comments": 12,
        "reactions": 58
      }
    },
    {
      "id": "user_wxyz9876stuv5432",
      "type": "organizationAnalyticsUser",
      "attributes": {
        "name": "Alan Turing",
        "username": "alan",
        "email": "[email protected]",
        "userType": "student",
        "active": true,
        "signupDate": "2025-08-21",
        "lastActivityDate": "2026-03-01",
        "padlets": 2,
        "posts": 19,
        "comments": 5,
        "reactions": 23
      }
    }
  ],
  "meta": {
    "status": "ready",
    "dateRange": { "from": "2026-01-01", "to": "2026-03-31" },
    "page": 1,
    "perPage": 2,
    "totalCount": 348,
    "totalPages": 174
  }
}

To export a whole roster, walk page until it passes meta.totalPages. Keep from, to and the filters identical across the walk. totalCount is computed per request, and changing a filter mid-walk repaginates the results underneath you.

Path Params
string
required
length between 16 and 22

Hashid of the organization where you are an admin, or a teacher for a classroom. Read it
from GET /me?include=organizations, which lists every wksp_ organization your key
belongs to. org_ organizations on padlet.org are not supported yet.

Query Params
string

First month of the range, inclusive. Send with to, or omit both to read the
organization's current billing term. Cannot precede January of five years ago.

string

Last month of the range, inclusive. The range counts both endpoints and may span at
most 24 of them, so to can be no more than 23 months after from. No later than
the current month.

status[]
array of strings

Keep only rows with this activity status. Repeatable; a row matching any listed value is kept, and listing both is the same as omitting the filter.

status[]
Allowed:
userType[]
array of strings

Keep only rows with this role. Repeatable. There is no owner value — owners are reported as admin, so admin covers them.

userType[]
Allowed:
string

Case-insensitive substring match on name or email.

string
enum
Defaults to name

Column to sort by. Rows with no value sort to the start of an ascending page and the end of a descending one.

string
enum
Defaults to asc
Allowed:
integer
≥ 1
Defaults to 1

1-based page number. (page - 1) * perPage may not exceed 1000000.

integer
1 to 100
Defaults to 25
Responses

Language
Credentials
Header
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/vnd.api+json