Customer profile
Profile of the authenticated customer plus signup, notification preferences, and the additional-info preference bag (gated by the DATA_CHARTS plan feature). Two static-HTML endpoints (Stripe checkout success/canceled landing pages and the user-agreement page) are public and intentionally not Bearer-authed.
Endpoint summary
| Method | Path | Auth scope |
|---|---|---|
| GET | /api/customer | bearer |
| POST | /api/customer | bearer (Firebase signup) |
| PUT | /api/customer | bearer |
| GET | /api/customer/user-agreement | none (HTML) |
| PUT | /api/customer/preferences/additional-info | bearer + DATA_CHARTS |
| GET | /api/customer/preferences/additional-info | bearer |
| DELETE | /api/customer/preferences/additional-info/{key} | bearer |
| PUT | /api/customer/preferences/notifications | bearer |
| GET | /api/customer/preferences/notifications | bearer |
| GET | /api/customer/subscription/success | none (HTML) |
| GET | /api/customer/payment/canceled | none (HTML) |
Get profile — GET /api/customer
curl -H "Authorization: Bearer $KEY" \
"https://portal.scrapewise.ai/api/scraper-api/api/customer?withStat=true"withStat=true includes rolled-up usage statistics (scraper count, run count, plan-quota usage).
Response (200)
{
"customerUniqueRef": "cust_abc123",
"email": "alice@example.com",
"firstname": "Alice",
"lastname": "Smith",
"agreeWithTerms": true,
"plan": "PRO",
"subscriptionStatus": "ACTIVE",
"statistic": {
"scraperCount": 12,
"runCountLast30d": 480,
"quotaUsage": { "MAX_SCRAPERS": 12, "MAX_GROUPS": 3 }
}
}Errors — 400 (N/A) / 401 / 403 (N/A) / 404 (N/A) / 429 / 500.
Create profile (post-signup) — POST /api/customer
POST /api/customer
Authorization: Bearer <firebase-jwt>
Content-Type: application/json
{
"firstname": "Alice",
"lastname": "Smith",
"email": "alice@example.com",
"agreeWithTerms": true
}First-time signup flow. The endpoint reads the Firebase user from the security context, creates a Customer document keyed by customerUniqueRef = firebaseUser.userId, and persists name + email + terms agreement.
Errors — 400 (validation failed) / 401 (no Firebase JWT) / 403 (N/A) / 404 (N/A) / 429 / 500.
Update profile — PUT /api/customer
PUT /api/customer
Authorization: Bearer <key>
{ "firstname": "Alice", "lastname": "Smith", "agreeWithTerms": true }Updates editable profile fields. customerUniqueRef and email are immutable here — those identity-bearing fields are managed via the auth provider.
Errors — 400 (validation) / 401 / 403 (N/A) / 404 (N/A) / 429 / 500.
Get user agreement — GET /api/customer/user-agreement
curl https://portal.scrapewise.ai/api/scraper-api/api/customer/user-agreementReturns the static terms-and-conditions HTML page (used by the signup flow). Public endpoint.
Errors — 400 (N/A) / 401 (N/A — public) / 403 (N/A — public) / 404 (N/A — static resource) / 429 / 500.
Update additional-info preference bag — PUT /api/customer/preferences/additional-info
PUT /api/customer/preferences/additional-info
Authorization: Bearer <key>
{ "dashboardLayout": "grid", "preferredCurrency": "EUR" }Stores arbitrary string-keyed preference values. Gated by the DATA_CHARTS plan feature. Schema is dynamic by design (additionalProperties: {type: string}).
Errors — 400 (N/A) / 401 / 402 (plan lacks DATA_CHARTS) / 403 (N/A — 402 used instead) / 404 (N/A) / 429 / 500.
Get additional-info — GET /api/customer/preferences/additional-info
Returns every key-value previously stored. Empty map if nothing has been saved.
Errors — 400 (N/A) / 401 / 403 (N/A) / 404 (N/A) / 429 / 500.
Delete a single additional-info key — DELETE /api/customer/preferences/additional-info/{key}
curl -X DELETE -H "Authorization: Bearer $KEY" \
https://portal.scrapewise.ai/api/scraper-api/api/customer/preferences/additional-info/dashboardLayoutIdempotent — deleting a non-existent key is a silent no-op. Returns the remaining bag.
Errors — 400 (N/A) / 401 / 403 (N/A) / 404 (N/A) / 429 / 500.
Notification preferences — PUT|GET /api/customer/preferences/notifications
PUT /api/customer/preferences/notifications
Authorization: Bearer <key>
{ "SCRAPER_RUN_FAILED": "EMAIL", "QUOTA_NEAR_LIMIT": "IN_APP" }Per-event notification preferences. Keys are event identifiers; values are the NotificationPreference enum (EMAIL, IN_APP, BOTH, NONE). GET returns the current map (empty if none set).
Errors — 400 (N/A) / 401 / 403 (N/A) / 404 (N/A) / 429 / 500.
Stripe landing pages
Public static-HTML pages Stripe redirects to after checkout:
GET /api/customer/subscription/success— checkout-success pageGET /api/customer/payment/canceled— checkout-canceled page
No Authorization header. Same permitAll exemption as the user-agreement page.
See also
- Billing & subscription — plan changes use the Stripe Checkout URL that lands here
- Plan features — which plan tier unlocks
DATA_CHARTS