Skip to main content

Developer Limits

Admins can configure per-developer and per-extension limits to control resource usage on the extension platform.

Sound limits​

Each extension has three configurable sound limits. Each limit resolves in priority order:

PrioritySourceWhere to set
1 (highest)Per-extension overrideAdmin → Hub → Extensions → the extension's row
2Per-developer overrideAdmin → Hub → Developers → developer detail → "Limit Overrides"
3 (lowest)Platform defaultSee defaults below
Limit keyDefaultDescription
max_sounds_per_extension50Maximum bundled sounds per extension
max_sound_file_size10 MB (10 485 760 bytes)Maximum size per individual sound file
max_sound_storage_bytes200 MB (209 715 200 bytes)Total sound storage across all sounds in an extension

The two size limits are stored in bytes; the admin forms take and display MB and convert on save. Every resolved limit is returned with a source marker of extension, developer, or default.

System extensions install with limit checks skipped - they are trusted and bypass sound-limit enforcement at install time.

Setting developer limits​

  1. Navigate to Admin → Hub → Developers
  2. Click a developer to open their detail page
  3. In the Limit Overrides section, set values for the three sound limits. Max Sounds per Extension accepts 0–500; the two size fields take MB.
  4. Each field has its own Save button, and a Reset button appears once the field has a value - Reset clears the override back to the platform default.

The Limit Overrides section is rendered only for admins holding developer-limits:edit.

The override applies to all extensions owned by this developer (unless an extension has its own override).

Setting per-extension limits​

  1. Navigate to Admin → Hub → Extensions
  2. Find the extension in the list
  3. Edit the limit cells inline - max sounds, file size, and storage each have their own editable cell, gated on developer-limits:edit

Leave a field empty to use the developer's limit or the platform default.

How limits are enforced​

  • CLI (lumio deploy) - fetches the resolved limits from the API and pre-flights count, per-file size, and total storage before uploading. Blocks the deploy with a descriptive error if exceeded. It falls back to the platform defaults (50 / 10 MB / 200 MB) when the limits call fails.
  • Server (upload endpoint) - validates the sound count, file sizes, and total storage in the manifest against the resolved limits. Returns a PlanLimitReached error if exceeded.
  • Server (install) - defence-in-depth check at install time. A sound count over the resolved limit logs a warning and truncates; total storage over the resolved limit fails the whole install. Neither should trigger if upload validation ran. Skipped entirely for system extensions.

Limit Requests​

Developers can request limit increases from their own developer limits page at /dashboard/settings/developer/limits. Admins review them on the global Limit Requests page at /developers/limit-requests, which has no sidebar entry - navigate to it directly. A per-developer Limit Requests section also appears on each developer's detail page.

Review workflow​

  1. Open /developers/limit-requests (or the Limit Requests section on a developer's detail page)
  2. Pick a status tab and open a request to see its details, including the requested value, the current value, and the developer's reason
  3. Approve - the requested value is applied automatically. Extension-scoped requests write the matching per-extension limit column; developer-scoped requests write a developer-level override.
  4. Reject - opens a dialog for review notes. The notes are optional at the API level but the reject dialog asks for them.

Every status change is written to a timeline of events and broadcast to the developer over a WebSocket channel, so the developer sees the decision without reloading.

Request statuses​

StatusMeaning
openSubmitted, waiting for admin review
in_reviewAn admin is reviewing the request
approvedApproved - the limit is applied automatically
rejectedRejected - review notes explain the reason

open is the submitted state. The review endpoint accepts only in_review, approved, or rejected - a request cannot be moved back to open.

The rest of the Developers area​

The sidebar's Hub → Developers sub-group carries four entries. Limit work happens on the developer detail page reached from the first one.

PageRoutePage gate
All Developers/developersdeveloper-verification:read
Developer Teams/developers/teamsdeveloper-limits:read
Developer Verifications/developers/verificationsdeveloper-verification:read
Developer Applications/developers/applicationsdeveloper-verification:read

Two more routes exist without a sidebar entry - navigate to them directly:

PageRoutePage gate
Limit Requests (global)/developers/limit-requestsdeveloper-limits:read
Developer Team detail/developers/teams/\{id\}developer-limits:read

The developer detail page at /developers/\{id\} also carries a revenue-split control (50–100% developer share) and a delete action, next to the Limit Overrides and Limit Requests sections. The delete action (on this page and in the developer list) is refused while the profile still has a revenue balance or a payout in progress (409 DEVELOPER_FUNDS_OUTSTANDING); the confirmation dialog then names that reason instead of closing.

When the balance cannot be paid out — no payout method, or the identity is not verified — and the developer asked for the deletion, an operator with developer-funds:release-deletion (and developer-verification:edit) releases it as a liability and deletes in one step (adminReleaseFundsAndDeleteDeveloper / POST /v1/admin/developers/\{id\}/release-funds-delete). The operator enters the support request reference and a reason; neither may contain names, e-mail addresses or contact data. The server decides the case and refuses a payable balance (409 DEVELOPER_FUNDS_PAYABLE, use the closing payout) and an in-flight payout (409 DEVELOPER_FUNDS_OUTSTANDING). The person receives a claim code by e-mail; if that mail cannot be sent, the response shows the code once so the operator can pass it on through the request channel. Lumio keeps only the amount, the case, the operator, the reference, the reason and a hash of the code (developer_released_balances), until the end of the third year after the release year. When the person comes back with the code, an operator with developer-funds:settle records the claim with Claim code presented on the developer list and credits the amount with Settle a released balance on the person's new, verified profile; see Settling a released balance. In the admin app, the delete confirmation dialog (developer list and detail page) offers Release balance as a liability and delete after the DEVELOPER_FUNDS_OUTSTANDING refusal, to operators who hold both permissions; the steps are in Releasing an unpayable developer balance.

Per-extension limits are edited on the Hub → Extensions pages (/extensions and /extensions/reviews), both gated on extension-review:read, with the limit cells themselves gated on developer-limits:edit.

API endpoints​

MethodPathPermissionDescription
GET/v1/admin/developers/\{id\}/limitsdeveloper-limits:readList developer limit overrides
PUT/v1/admin/developers/\{id\}/limitsdeveloper-limits:editSet/remove a developer limit override
PATCH/v1/admin/extensions/\{id\}/limitsdeveloper-limits:editSet/clear per-extension limit overrides
GET/v1/admin/limit-requestsdeveloper-limits:readList all limit requests
GET/v1/admin/developers/\{id\}/limit-requestsdeveloper-limits:readList limit requests for a developer
PUT/v1/admin/limit-requests/\{id\}developer-limits:editReview (approve/reject) a limit request
GET/v1/admin/limit-requests/\{id\}/eventsdeveloper-limits:readGet timeline events for a limit request

GraphQL: adminDeveloperLimits, adminSetDeveloperLimit, adminSetExtensionLimits, adminAllLimitRequests, adminDeveloperLimitRequests, adminLimitRequestEvents, adminReviewLimitRequest - see GraphQL reference.

The admin app calls these through its own proxy routes: /api/developers/\{id\}/limits, /api/extensions/\{id\}/limits, /api/limit-requests, /api/limit-requests/\{requestId\}, and /api/limit-requests/\{requestId\}/events.