Developer Apps API
Developer Apps API
Base path: /api/v1/apps
All endpoints require authentication via Authorization: Bearer <accessToken>.
List My Apps
GET /api/v1/apps?page=1&limit=20&status=active&listed=true| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Results per page (max 100) |
status | string | -- | Filter: active or inactive |
listed | boolean | -- | Filter by marketplace listing status |
Response (200):
{
"status": 200,
"message": "Apps fetched",
"data": {
"items": [
{
"app_id": 2,
"app_type": "platform",
"name": "SeloraX Messaging",
"slug": "selorax-messaging",
"icon": "https://cdn.example.com/icon.png",
"short_description": "Automated SMS for order updates",
"is_listed": 1,
"is_active": 1,
"created_at": "2026-01-15T08:30:00.000Z",
"updated_at": "2026-02-28T10:00:00.000Z"
}
],
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1
}
}Get App Details
GET /api/v1/apps/:appIdResponse (200):
{
"status": 200,
"message": "App fetched",
"data": {
"app_id": 2,
"app_type": "platform",
"name": "SeloraX Messaging",
"slug": "selorax-messaging",
"icon": "https://cdn.example.com/icon.png",
"screenshots": ["https://cdn.example.com/shot-1.png"],
"description": "Full description of the app...",
"short_description": "Automated SMS for order updates",
"homepage_url": "https://messaging.selorax.com",
"app_url": "https://messaging.selorax.com/embed",
"setup_url": null,
"webhook_url": "https://api.messaging.selorax.com/api/messaging/oauth",
"webhook_receive_url": "https://api.messaging.selorax.com/api/messaging/webhooks",
"webhook_topics": ["order.status_changed"],
"redirect_urls": ["https://messaging.selorax.com/oauth/callback"],
"requested_scopes": ["read:orders", "read:customers", "read:store", "billing"],
"developer_name": "SeloraX Team",
"developer_email": "[email protected]",
"pricing_type": "usage",
"pricing_amount": 0,
"fee_payer": "developer",
"category": "messaging",
"metadata": null,
"is_listed": 1,
"is_active": 1,
"client_id": "sx_app_1b16e193a28d2640d2d9734dbf4907e8",
"created_by": 42,
"created_at": "2026-01-15T08:30:00.000Z",
"updated_at": "2026-02-28T10:00:00.000Z"
}
}Errors:
404 APP_NOT_FOUND— App not found or not owned by you
Create App
POST /api/v1/apps
Content-Type: application/jsonRequest Body:
{
"name": "My Custom App",
"slug": "my-custom-app",
"redirect_urls": ["https://example.com/oauth/callback"],
"requested_scopes": ["read:orders", "read:products", "billing"],
"description": "A detailed description of what the app does",
"short_description": "Brief marketplace summary",
"icon": "https://cdn.example.com/icon.png",
"screenshots": ["https://cdn.example.com/shot-1.png"],
"homepage_url": "https://example.com",
"app_url": "https://example.com/embed",
"setup_url": "https://example.com/setup",
"webhook_url": "https://api.example.com/oauth",
"webhook_receive_url": "https://api.example.com/webhooks",
"webhook_topics": ["order.status_changed", "order.created"],
"developer_name": "Acme Labs",
"developer_email": "[email protected]",
"pricing_type": "subscription",
"pricing_amount": 499,
"fee_payer": "developer",
"category": "analytics",
"metadata": { "version": "1.0" }
}Required fields: name, redirect_urls (min 1), requested_scopes (min 1)
Validation:
name: 3-255 charactersslug: 3-255 chars, lowercase letters, numbers, dashes onlydescription: max 8000 charactersshort_description: max 500 charactersscreenshots: max 10 URLsfee_payer:"developer"or"merchant"
Response (201):
{
"status": 201,
"message": "App created",
"data": {
"app_id": 5,
"name": "My Custom App",
"slug": "my-custom-app",
"clientId": "sx_app_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"clientSecret": "sx_secret_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"sessionSigningKey": "a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"
}
}Save your credentials
The clientSecret and sessionSigningKey are shown only once at creation time. Store them securely — they cannot be retrieved later. If lost, use the rotation endpoints to generate new ones.
Errors:
409 SLUG_EXISTS— Slug already in use409 DUPLICATE_FIELD— Unique constraint violation
Update App Profile
PATCH /api/v1/apps/:appId
Content-Type: application/jsonAll fields are optional. Only include fields you want to change:
{
"icon": "https://cdn.example.com/new-icon.png",
"screenshots": ["https://cdn.example.com/shot-1.png", "https://cdn.example.com/shot-2.png"],
"short_description": "Updated description",
"developer_name": "Acme Labs v2"
}Response (200):
{
"status": 200,
"message": "App updated",
"data": {
"app_id": 5,
"name": "My Custom App",
"slug": "my-custom-app",
"icon": "https://cdn.example.com/new-icon.png",
"screenshots": ["https://cdn.example.com/shot-1.png", "https://cdn.example.com/shot-2.png"],
"short_description": "Updated description",
"updated_at": "2026-02-28T12:00:00.000Z"
}
}Delete App
DELETE /api/v1/apps/:appIdSoft-deletes the app (sets deleted_at, marks inactive).
Response (200):
{
"status": 200,
"message": "App deleted",
"data": { "app_id": 5 }
}Update Listing Status
Controls marketplace visibility. When is_listed is true, merchants can discover and install your app from the marketplace.
PATCH /api/v1/apps/:appId/listing
Content-Type: application/json{
"is_listed": true
}Response (200):
{
"status": 200,
"message": "App listing updated",
"data": { "app_id": 5, "is_listed": 1 }
}Update Active Status
Controls whether the app functions. When is_active is false, existing installations stop working.
PATCH /api/v1/apps/:appId/status
Content-Type: application/json{
"is_active": true
}Response (200):
{
"status": 200,
"message": "App status updated",
"data": { "app_id": 5, "is_active": 1 }
}Rotate Client Secret
Generates a new client secret. The old secret is immediately invalidated.
POST /api/v1/apps/:appId/rotate-secretResponse (200):
{
"status": 200,
"message": "Client secret rotated",
"data": {
"app_id": 5,
"client_secret": "sx_secret_new..."
}
}After rotating, update the secret in all your backend services immediately. The old secret will no longer work for token exchange or client credential authentication.
Regenerate Signing Key
Generates a new session signing key. Existing session tokens signed with the old key become invalid.
POST /api/v1/apps/:appId/regenerate-signing-keyResponse (200):
{
"status": 200,
"message": "Session signing key regenerated",
"data": {
"app_id": 5,
"session_signing_key": "a1b2c3d4..."
}
}App Settings
Get all settings grouped by category:
GET /api/v1/apps/:appId/settingsResponse (200):
{
"status": 200,
"message": "Settings fetched",
"data": {
"oauth": {
"redirect_urls": ["https://example.com/oauth/callback"],
"requested_scopes": ["read:orders", "billing"]
},
"webhooks": {
"webhook_receive_url": "https://api.example.com/webhooks",
"webhook_topics": ["order.status_changed"]
},
"embed": {
"app_url": "https://example.com/embed",
"setup_url": null
},
"billing": {
"pricing_type": "subscription",
"pricing_amount": 499,
"fee_payer": "developer"
},
"developer": {
"developer_name": "Acme Labs",
"developer_email": "[email protected]"
}
}
}Update Settings by Category
Each settings group has its own PATCH endpoint:
PATCH /api/v1/apps/:appId/settings/oauth
PATCH /api/v1/apps/:appId/settings/webhooks
PATCH /api/v1/apps/:appId/settings/embed
PATCH /api/v1/apps/:appId/settings/billing
PATCH /api/v1/apps/:appId/settings/developerExample — update webhook settings:
{
"webhook_receive_url": "https://api.example.com/webhooks/v2",
"webhook_topics": ["order.status_changed", "order.created"]
}List Installations
View all stores that have installed your app:
GET /api/v1/apps/:appId/installations?page=1&limit=20&status=active| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Results per page (max 100) |
status | string | -- | Filter: active, uninstalled, etc. |
Response (200):
{
"status": 200,
"message": "Installations fetched",
"data": {
"items": [
{
"installation_id": 2,
"store_id": 22,
"status": "active",
"granted_scopes": ["read:orders", "read:customers", "read:store", "billing"],
"token_expires_at": "2026-02-28T22:00:00.000Z",
"last_used_at": "2026-02-28T10:30:00.000Z",
"request_count": 1547,
"created_at": "2026-01-20T09:00:00.000Z",
"updated_at": "2026-02-28T10:30:00.000Z"
}
],
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1
}
}Billing Charges
View charges created by your app across all stores:
GET /api/v1/apps/:appId/billing/charges?page=1&limit=20&status=completed| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Results per page (max 100) |
status | string | -- | Filter by charge status |
Response (200):
{
"status": 200,
"message": "Charges fetched",
"data": {
"items": [
{
"charge_id": 8,
"store_id": 22,
"installation_id": 2,
"charge_type": "wallet_topup",
"name": "Wallet Top-up",
"amount": 500.00,
"base_amount": 500.00,
"currency": "BDT",
"fee_payer": "developer",
"commission_rate": 0.1,
"platform_amount": 50.00,
"gateway_fee_rate": 0.025,
"gateway_fee_amount": 12.50,
"developer_amount": 437.50,
"status": "completed",
"created_at": "2026-02-20T09:00:00.000Z",
"activated_at": "2026-02-20T09:05:00.000Z"
}
],
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1
}
}Revenue Ledger
View the developer revenue ledger (platform commission breakdown):
GET /api/v1/apps/:appId/billing/revenue?page=1&limit=20Response (200):
{
"status": 200,
"message": "Revenue fetched",
"data": {
"items": [
{
"ledger_id": "1",
"app_id": 2,
"charge_id": 8,
"from_wallet_amount": "500.00",
"to_wallet_amount": "400.00",
"amount": "500.00",
"type": "topup",
"description": "Wallet Top-up",
"created_at": "2026-02-20T09:05:00.000Z"
}
],
"page": 1,
"limit": 20,
"total": 1,
"totalPages": 1
}
}Developer Balance
Check your available balance (earnings minus payouts):
GET /api/v1/apps/:appId/billing/balanceResponse (200):
{
"status": 200,
"message": "Balance fetched",
"data": {
"app_id": 2,
"total_earned": "1250.00",
"total_paid_out": "0.00",
"available_balance": "1250.00",
"currency": "BDT",
"updated_at": "2026-02-28T10:00:00.000Z"
}
}App Overview Dashboard
Get aggregated stats for your app:
GET /api/v1/apps/:appId/overviewResponse (200):
{
"status": 200,
"message": "App overview fetched",
"data": {
"installations": {
"active": 12,
"total": 15
},
"charges": {
"count": 47,
"total_amount": "23500.00",
"total_developer_amount": "18800.00"
},
"webhooks": {
"active_subscriptions": 12,
"delivered_7d": 342,
"failed_7d": 3
},
"recent_activity": {
"latest_installation": {
"installation_id": 15,
"store_id": 45,
"status": "active",
"created_at": "2026-02-27T14:30:00.000Z"
},
"latest_charge": {
"charge_id": 47,
"name": "Wallet Top-up",
"amount": 500.00,
"status": "completed",
"created_at": "2026-02-28T09:00:00.000Z"
},
"latest_delivery": {
"delivery_id": "342",
"event_topic": "order.status_changed",
"status": "success",
"created_at": "2026-02-28T10:15:00.000Z"
}
}
}
}