Developer Account
Everything you build on SSP starts with a developer account in the Developer Portal. The account owns your API keys, your projects, your sandboxes, and the plugins you publish.
A developer account lives in its own namespace — it is not an SSP Manager staff login. Registering as a developer never collides with (or grants access to) a restaurant's platform account, and a developer-portal session is rejected by the Manager, Waiter, and Kitchen apps by design.
The onboarding path
Step 1 — Register
Sign up at developer.ssppos.com/register.
| Field | Rules |
|---|---|
name | Required, max 255 characters |
email | Required, valid email, max 255, must be unique among developer accounts |
password | Required, minimum 8 characters, max 255 |
company | Optional, max 255 characters |
Registration creates an unverified account and emails a verification link. It deliberately returns no session token and no API key — a credential is never issued against an unverified email address.
An unverified account is rejected with the same "Invalid credentials" message as a wrong password, and every failed attempt counts toward a rate limiter. Trying to log in before you click the verification link can lock you out temporarily even though your password is correct.
Emails are normalised to lowercase, so Dev@Example.com and dev@example.com
are the same account.
Lost or expired verification link
Request a new one from the portal's verification screen. The response is deliberately identical whether the address is unknown, already verified, or throttled — so it can't be used to discover which emails are registered.
Step 2 — Log in
A successful login returns a Portal JWT:
- Lifetime is 4 hours by default, with no refresh — you log in again when it expires.
- It is typed for the portal only. It is not accepted by the Manager, Waiter, Kitchen, or Guest apps.
- The portal stores it in an httpOnly cookie and proxies GraphQL calls server-side, so the token is never exposed to browser JavaScript.
Login failures are intentionally opaque: unknown email, wrong password,
suspended account, and unverified account all return the same
Invalid credentials. error and all increment the same per-email rate limiter.
Forgotten password
Use Forgot password in the portal. As with verification, the response is always the same regardless of whether the address exists.
Step 3 — Accept the developer agreements
Before you can mint credentials or move a plugin through its lifecycle, you must accept the current version of every mandatory developer document:
| Document | What it covers |
|---|---|
| Developer Agreement | The contract to hold a developer account and build against the API and sandbox |
| Plugin Distribution Agreement | Publishing, review, IP, revenue, suspension and takedown |
| API Terms | Rate limits, key handling, and data-use restrictions |
| Acceptable Use Policy | What plugins and integrations may and may not do |
This gate is enforced, not advisory. While any document is outstanding,
portal operations fail with extensions.code: DEVELOPER_AGREEMENT_REQUIRED
(the sandbox-operator handoff returns the same code as JSON with 403).
What still works while you are blocked, by design:
- Reading your legal status and your profile — the acceptance screen needs them.
- Accepting the terms — that's the way out.
- Listing and revoking your API keys. A leaked credential must be killable without signing a contract under duress. Minting a new key is gated; containment is not.
Acceptance is recorded against the exact version that was published when you accepted, along with the timestamp, IP, and user agent. Re-accepting the same version is idempotent and preserves the original acceptance date. When a document is republished at a new version, you are prompted again.
Acceptance is a deliberate human action, so it is portal-session-only. API keys are therefore never blocked by the gate — otherwise a version bump would silently break running CI with no way for the key to remedy its own block.
Step 4 — Mint an API key (ssp_dev_)
Developer API keys are for CI and programmatic access. You do not need one to use the portal UI — the portal authenticates with your session.
From API Keys → Generate key:
| Property | Value |
|---|---|
| Format | ssp_dev_ + 32 random characters (40 total) |
| Scopes | plugins:read, plugins:write (both by default; no other scopes are accepted) |
| Active-key cap | 10 per account — revoke an unused key to create another |
| Rate limit | 60 requests/minute per key |
| Expiry | None by default |
Send it as a bearer token:
curl https://api.ssppos.com/graphql \
-H "Authorization: Bearer ssp_dev_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{"query":"{ developerProfile { name email projects_count plugins_count } }"}'
The plaintext key is returned exactly once, at creation. It cannot be retrieved afterwards — only a masked prefix is ever queryable. Copy it straight into your secret store.
Key hygiene
Each key records last_used_at, last_used_ip, and a usage_count, so you can
spot a key being used from somewhere unexpected. Revoked keys stay in the list
as history rather than disappearing.
Revoking a key is immediate, and also suspends any sandbox operator sessions that key owns.
usage_count on a developer key counts developer-API traffic
(Authorization: Bearer ssp_dev_…) only. Your plugin's runtime data calls use a
pik_ key and are counted separately, per installation.
Step 5 — Create a project
A project is the unit of work in the portal. It bundles:
- one plugin (created later, from the project),
- one sandbox,
- a team of developer accounts with roles.
| Field | Rules |
|---|---|
name | Required, max 255. Lowercase letters, digits and hyphens only; must start and end with a letter or digit (e.g. acme-payments) |
description | Optional, max 2000 characters |
The account that creates the project becomes its owner.
createPluginFromProject requires a project, so there is no standalone "new
plugin" flow — you always create the plugin from inside its project. The
portal's Plugins screen is a read-only roll-up across your projects.
Archiving
Owners can archive a project, and unarchive it again later. Unarchiving is idempotent when the project is already active.
Step 6 — Invite your team
Add members by their developer account email (they must already have an account). Membership is anchored on the account, so it survives a member rotating their API keys.
| Role | Can do |
|---|---|
| owner | Everything, including archiving the project and changing owner-level settings |
| admin | Manage members, provision/regenerate sandbox credentials, create and edit the plugin, rotate the webhook secret, fire test webhooks |
| member | Work in the project and reset the sandbox |
| viewer | Read-only |
Rules worth knowing:
- Adding, removing, or re-roling a member requires owner or admin.
- An admin cannot promote anyone to owner, and cannot remove the owner.
- Sandbox provisioning and key regeneration require owner or admin; resetting sandbox data is also open to members.
What comes next
- Getting Started — provision a sandbox and make your first API call
- Sandboxes — lifecycle, resets, expiry, and opening SSP Manager against your sandbox
- Plugin Lifecycle — draft → review → publish, pricing, and marketplace listing
Support
- Email: developers@ssppos.com
- Examples: github.com/ssppos/examples