API Endpoint Affected: /api/v1/licenses/{id}/seats
Reference Documentation: https://snipe-it.readme.io/reference/licensesidseats
Issue Description
The Snipe-IT API endpoint for retrieving license seats (/api/v1/licenses/{id}/seats) does not return all unique seat IDs for a license as described in the documentation. Instead, it appears to paginate results by default (likely with a hidden or undocumented limit), returning only a subset of seats. This requires manual implementation of pagination (using parameters like offset and limit) to fetch all seats, which is not mentioned in the endpoint-specific documentation. This leads to incomplete data retrieval when calling the endpoint without pagination parameters, potentially causing errors in applications relying on the API to return complete results (e.g., "no available seats" errors when seats exist on subsequent pages).
This inconsistency between the documented behavior ("returns all unique Seat IDs") and actual implementation hinders development and requires workarounds, such as custom pagination logic in client code.
Reproduction Steps
- Set up or access a Snipe-IT instance with a license that has a large number of seats (e.g., >50, assuming a default limit around 50-100).
- Authenticate with the API using a valid Bearer token.
- Make a GET request to the endpoint without any query parameters:
GET /api/v1/licenses/{license_id}/seats
(Replace {license_id} with a valid license ID having many seats.)
- Observe the response JSON, noting the number of seats returned in the
rows array and the total field.
- If the
total is greater than the number of items in rows, confirm that not all seats are returned in a single call.
- To fetch additional seats, add pagination parameters (e.g.,
?offset=50&limit=50) and repeat the request to see subsequent pages.
Example using curl:
curl -H "Authorization: Bearer {your_api_token}" "https://your-snipeit-instance.com/api/v1/licenses/{license_id}/seats"
Expected Behavior
Based on the documentation (https://snipe-it.readme.io/reference/licensesidseats), the endpoint should return all unique Seat IDs for the specified license in a single response, without requiring pagination parameters. The response should include a complete list in the rows array, matching the total count, regardless of the number of seats.
If pagination is intended, the documentation should explicitly describe supported parameters (e.g., limit, offset) and default values, similar to other endpoints like /users or general API throttling notes.
Actual Behavior
- The endpoint returns only a paginated subset of seats (e.g., first 50-100 seats, based on a default
limit).
- The
total field in the response indicates the full count, but the rows array contains only the current page's seats.
- To retrieve all seats, manual pagination is required using undocumented parameters like
offset and limit (inferred from general Snipe-IT API patterns, such as "standard pagination using the offset parameter" mentioned in API throttling docs: https://snipe-it.readme.io/reference/api-throttling).
- Without pagination, applications may incorrectly assume no more seats exist, leading to errors like "no available seats for license ID {id}" when unassigned seats are on later pages.
Technical Details
- API Version: v1 (as per the endpoint path).
- Request Method: GET.
- Query Parameters Used in Workaround:
offset: Starting point for results (e.g., 0 for first page).
limit: Number of results per page (e.g., 500; no documented maximum).
- Other inferred parameters:
order (e.g., "asc"), sort (e.g., "name"), though not always necessary.
- Response Format: JSON object with
total (integer) and rows (array of seat objects, each with id, method.license_id, method.assigned_user.record, etc.).
- Environment:
- Tested on a Snipe-IT instance.
- Client: Go application using HTTP requests.
- Workaround Implemented: Manual pagination loop in client code:
- Start with
page=1, size=500.
- Increment
page until an unassigned seat is found or rows length < size.
- Example:
https://ledger.snipe-it.io/api/v1/licenses/{id}/seats?page=4&size=500&order=asc&sort=name.
- Related Documentation Issues:
- Impact: Affects integrations processing large licenses (e.g., >500 seats), causing incomplete data and requiring custom code to paginate.
Suggested Fix:
- Update the endpoint to optionally return all seats (e.g., with
?all=true or no limit by default if feasible).
- Document pagination parameters (
limit, offset, defaults) explicitly in the /licenses/{id}/seats reference.
- If possible, add a note on maximum page size to avoid server strain.
API Endpoint Affected:
/api/v1/licenses/{id}/seatsReference Documentation: https://snipe-it.readme.io/reference/licensesidseats
Issue Description
The Snipe-IT API endpoint for retrieving license seats (
/api/v1/licenses/{id}/seats) does not return all unique seat IDs for a license as described in the documentation. Instead, it appears to paginate results by default (likely with a hidden or undocumented limit), returning only a subset of seats. This requires manual implementation of pagination (using parameters likeoffsetandlimit) to fetch all seats, which is not mentioned in the endpoint-specific documentation. This leads to incomplete data retrieval when calling the endpoint without pagination parameters, potentially causing errors in applications relying on the API to return complete results (e.g., "no available seats" errors when seats exist on subsequent pages).This inconsistency between the documented behavior ("returns all unique Seat IDs") and actual implementation hinders development and requires workarounds, such as custom pagination logic in client code.
Reproduction Steps
GET /api/v1/licenses/{license_id}/seats(Replace
{license_id}with a valid license ID having many seats.)rowsarray and thetotalfield.totalis greater than the number of items inrows, confirm that not all seats are returned in a single call.?offset=50&limit=50) and repeat the request to see subsequent pages.Example using curl:
Expected Behavior
Based on the documentation (https://snipe-it.readme.io/reference/licensesidseats), the endpoint should return all unique Seat IDs for the specified license in a single response, without requiring pagination parameters. The response should include a complete list in the
rowsarray, matching thetotalcount, regardless of the number of seats.If pagination is intended, the documentation should explicitly describe supported parameters (e.g.,
limit,offset) and default values, similar to other endpoints like/usersor general API throttling notes.Actual Behavior
limit).totalfield in the response indicates the full count, but therowsarray contains only the current page's seats.offsetandlimit(inferred from general Snipe-IT API patterns, such as "standard pagination using the offset parameter" mentioned in API throttling docs: https://snipe-it.readme.io/reference/api-throttling).Technical Details
offset: Starting point for results (e.g., 0 for first page).limit: Number of results per page (e.g., 500; no documented maximum).order(e.g., "asc"),sort(e.g., "name"), though not always necessary.total(integer) androws(array of seat objects, each withid,method.license_id,method.assigned_user.record, etc.).page=1,size=500.pageuntil an unassigned seat is found orrowslength <size.https://ledger.snipe-it.io/api/v1/licenses/{id}/seats?page=4&size=500&order=asc&sort=name.offset-based pagination (https://snipe-it.readme.io/reference/api-throttling), but this is not cross-referenced in endpoint-specific pages.Suggested Fix:
?all=trueor no limit by default if feasible).limit,offset, defaults) explicitly in the/licenses/{id}/seatsreference.