Skip to main content
The Developer Platform lets third-party developers register and manage apps, integrate them into merchant stores via OAuth 2.0, issue API keys for direct access, and subscribe to real-time business events via webhooks. There are two route groups: /developer/* for developer-account-scoped operations (building and publishing apps) and /admin/* for merchant-scoped operations (installing apps, managing webhooks and API keys from within a store). Base URL https://api.genuka.com · Auth Authorization: Bearer <token> + X-Company: <companyId> · Getting Started

Endpoints at a glance


Developer Auth

These endpoints use the developer guard (Laravel Sanctum). They do not require X-Company header.

GET /2023-11/developer/auth/login

No-op endpoint — returns a redirect placeholder for the login form. Not useful for API clients. Success response (200 OK): HTML redirect or empty body.

POST /2023-11/developer/auth/login

Authenticate a developer account and return a Sanctum access token. Request body
Success response (200 OK):
Error responses
  • 401{ "message": "Invalid email or password." }

POST /2023-11/developer/auth/logout

Revoke the current developer access token and its refresh token. Request body: None — authentication is performed via the Authorization: Bearer <token> header only.
Success response (200 OK):
Error responses
  • 401{ "message": "Unauthenticated." }

GET /2023-11/developer/auth/register

No-op endpoint — redirect placeholder. Not useful for API clients.

POST /2023-11/developer/auth/register

Register a new developer account. Creates both a Company (type=developer) and a Developer user, then issues a Sanctum token. Request body
Success response (200 OK):
Error responses
  • 400{ "message": "Company payload is required" }
  • 400{ "message": "User with given email already exists. Please login" }

POST /2023-11/developer/auth/password/email

Send a password-reset link to a developer email address. Request body
Success response (200 OK):
Error responses
  • 400{ "message": "We can't find a user with that email address." }
  • 422{ "message": "The given data was invalid.", "errors": { "email": ["The email field is required."] } }

POST /2023-11/developer/auth/password/reset

Reset developer password using the token from the reset email. Request body
Success response (200 OK):
Error responses
  • 400{ "message": "This password reset token is invalid." }

Developer Profile

GET /2023-11/developer/me

Get the authenticated developer’s profile including company stats.
Success response (200 OK):
Error responses
  • 401{ "message": "Unauthenticated." }

DELETE /2023-11/developer/me/delete

Permanently delete the authenticated developer account. All Passport tokens are revoked first.
Success response (200 OK):
Error responses
  • 401{ "message": "Unauthenticated." }

PUT /2023-11/developer/me/metadata

Merge arbitrary key-value pairs into the developer’s metadata JSON column. Existing keys not in the request are preserved. Request body: Any flat JSON object. All top-level keys (except the reserved keys metadata and anonymous) are merged into the stored metadata object. There is no fixed schema — send any key-value pairs your application needs.
Success response (200 OK): Returns the updated developer user resource.
Error responses
  • 401{ "message": "Unauthenticated." }

Apps (Developer)

GET /2023-11/developer/apps

List apps. Developer-type companies see only their own apps. Business-type companies see only published apps. Super-admins see all. Query parameters
Success response (200 OK):
Error responses
  • 401{ "message": "Unauthenticated." }

POST /2023-11/developer/apps

Create a new app. A Passport OAuth client is automatically created and the client_id/client_secret are returned (the only time the secret is shown in full). Request body
Success response (200 OK): App object with client_secret shown in full (only revealed at creation time).
Error responses
  • 400{ "error": "The name has already been taken." }
  • 422{ "message": "The given data was invalid.", "errors": { "name": ["The name field is required."] } }

GET /2023-11/developer/apps/{app}

Get details of a single app. Path parameters
Success response (200 OK):
Error responses
  • 404{ "message": "No query results for model." }

PUT /2023-11/developer/apps/{app}

Update an existing app. Only fields provided are updated. Pass regenerate_keys: true to rotate the OAuth client ID and secret. Path parameters Request body
Success response (200 OK): Updated app resource.
Error responses
  • 400{ "error": "..." }
  • 404{ "message": "No query results for model." }

DELETE /2023-11/developer/apps/{app}

Delete an app. Only allowed when status is draft and the calling user has the admin role in the owning company. Path parameters
Success response (200 OK):
Error responses
  • 403{ "error": "App does not belong to the company" }
  • 403{ "error": "App is not in draft status" }
  • 403{ "error": "You are not authorized to delete this app" }

GET /2023-11/developer/apps/{app}/secret

Reveal the full client_secret for an app. The secret is masked (•••) in all other responses. Path parameters
Success response (200 OK): App resource with client_secret in plaintext.
Error responses
  • 404{ "message": "No query results for model." }

PATCH /2023-11/developer/apps/{app}/status

Change the lifecycle status of an app. Moving to pending records submitted_at; moving to published records published_at and triggers an email notification to the developer admin. Path parameters Request body
Success response (200 OK): Updated app resource.
Error responses
  • 422{ "message": "The given data was invalid.", "errors": { "status": ["..."] } }

App Reviews

GET /2023-11/developer/apps-reviews and GET /2023-11/admin/apps-reviews

List app reviews. Developer-company users see reviews for their own apps only; super-admins see all. Query parameters
Success response (200 OK): Paginated list of review objects.

POST /2023-11/developer/apps-reviews and POST /2023-11/admin/apps-reviews

Create a new review record for an app. Request body
Success response (201 Created): Review object with app and reviewer relations loaded.

GET /2023-11/developer/apps-reviews/{reviewId} and GET /2023-11/admin/apps-reviews/{reviewId}

Get a single review with its related app. Path parameters Success response (200 OK): Review object with app loaded.

PUT /2023-11/developer/apps-reviews/{reviewId} and PUT /2023-11/admin/apps-reviews/{reviewId}

Update an existing review. Path parameters Request body Success response (200 OK): Updated review with app and reviewer.

DELETE /2023-11/developer/apps-reviews/{reviewId} and DELETE /2023-11/admin/apps-reviews/{reviewId}

Delete a review. Path parameters Success response (200 OK):

App Shortcuts

App shortcuts are deep-link entries injected into the merchant dashboard UI by an installed app.

GET /2023-11/developer/app-shortcuts

List app shortcuts. Results are filtered by the authenticated company via query filters. Query parameters
Success response (200 OK): Paginated list of app shortcut objects.

POST /2023-11/developer/app-shortcuts

Create an app shortcut. Request body
Success response (201 Created): App shortcut resource object.

GET /2023-11/developer/app-shortcuts/{appShortcut}

Get a single shortcut. Only returned if the shortcut belongs to the requesting company. Path parameters Success response (200 OK): Shortcut resource object.
Error responses
  • 404{ "error": "App shortcut not available for this company" }

PUT /2023-11/developer/app-shortcuts/{appShortcut}

Update a shortcut. Only available if the shortcut belongs to the requesting company. Path parameters Request body
Success response (200 OK): Updated shortcut resource.
Error responses
  • 404{ "error": "App shortcut not available for this company" }

DELETE /2023-11/developer/app-shortcuts/{appShortcut}

Delete a shortcut. Path parameters Success response (200 OK):
Error responses
  • 404{ "error": "App shortcut not available for this company" }

OAuth 2.0

The Genuka OAuth flow allows apps to act on behalf of a merchant company. The flow is:
  1. Initiate — app calls /oauth/initiate with its client_id to get a short-lived request_code.
  2. Authorize — merchant user approves in the dashboard, which calls /oauth/authorize. On approval, an authorization code is generated and the callback URL receives an HMAC-signed redirect.
  3. Exchange — app exchanges the code for an access token (see the OAuth token exchange endpoint, not listed separately here; call /2023-11/admin/apps/oauth/token directly with client credentials).
  4. Refresh — call /oauth/refresh with the refresh token to rotate credentials.

POST /2023-11/developer/apps/oauth/initiate and POST /2023-11/admin/apps/oauth/initiate

Begin the authorization flow. Returns a request_code that the app should pass to the authorization UI. Request body
Success response (200 OK):

POST /2023-11/developer/apps/oauth/authorize and POST /2023-11/admin/apps/oauth/authorize

Approve or deny an authorization request. On approval, creates or updates an AppInstall record, generates an auth code, and returns the signed redirect URL that the frontend should follow. Requires the requesting company to have an active subscription if the app has a non-zero price. Request body
Success response (200 OK):
Error responses
  • 400{ "error": "Invalid company" }
  • 400{ "error": "Invalid app" }
  • 200{ "message": "Authorization denied" } (when approved: false or subscription missing)

POST /2023-11/developer/apps/oauth/refresh and POST /2023-11/admin/apps/oauth/refresh

Exchange a refresh token for new access and refresh tokens. Request body
Success response (200 OK):
Error responses
  • 400{ "error": "Invalid or expired refresh token" }

Apps (Admin / Merchant)

GET /2023-11/admin/apps

List apps visible to the merchant. Business-company users see published apps only; super-admins see all. Same query parameters as GET /2023-11/developer/apps. Success response (200 OK):

GET /2023-11/admin/apps/{app}

Get a single app (merchant view). Path parameters Success response (200 OK): App resource.

PATCH /2023-11/admin/apps/{app}/status

Update app status. For platform admins / super-admins to publish, reject, or archive apps. Path parameters Request body
Success response (200 OK): Updated app resource.

POST /2023-11/admin/apps/subscribe

Subscribe a company to an app plan. Initiates payment via Stripe or PawaPay and returns a redirect URL to the payment page. Request body
Success response (200 OK):
Error responses
  • 400{ "message": "Payment URL unavailable", "payment_method": "stripe" }
  • 422 — validation errors

Installed Apps

GET /2023-11/admin/apps-installed

List all app installations for the current company. Query parameters
Success response (200 OK):

GET /2023-11/admin/apps-installed/{appInstall}

Get a single installation. Also returns a signed redirect_url that the app can use to open the merchant’s store context. Path parameters
Success response (200 OK):
Error responses
  • 404{ "error": "App not installed by the company" }

DELETE /2023-11/admin/apps-installed/{appInstall}

Uninstall an app from the company. Dispatches a webhook notification to the app’s webhook_url if configured. Path parameters
Success response (200 OK):
Error responses
  • 404{ "error": "App not installed by the company" }

API Keys

API keys allow programmatic access to the Genuka API without OAuth. Only users with the admin, manager, or superadmin role can list keys.

GET /2023-11/admin/apikeys

List API keys. Query parameters
Success response (200 OK): Paginated list of API key objects.
Error responses
  • 401{ "error_code": "UNAUTHORIZED", "message": "You are not authorized to list apikeys.", "role": "..." }

POST /2023-11/admin/apikeys

Create a new API key. The key value is randomly generated (32 characters). Expires in one year by default. Request body
Success response (200 OK): API key resource — includes the key value; store it immediately as it is not re-displayable.

DELETE /2023-11/admin/apikeys/{apikey}

Permanently delete an API key. Path parameters
Success response (200 OK):

Webhooks

Webhooks let your app receive real-time POST notifications when business events occur. Genuka signs each delivery with an HMAC-SHA256 signature using the webhook’s secret. The secret is only returned at creation time and after a regeneration. Webhooks are automatically disabled after 10 consecutive delivery failures.

Available events

Events follow the pattern {resource}.{action}. Resources include: delivery, order, customer, invoice, payment, address, shop, product, product_variant, stock, stock_warehouse, supplier, supplier_product, tag, taggable, user, tax, discount, pickup_location, shipping_fee, warehouse, transfer, order_product, product_return, service, campaign, campaign_template, campaign_customer, inbox_conversation, inbox_message. Actions for most resources: created, updated, deleted, restored.

GET /2023-11/admin/webhooks

List webhooks for the current company. Query parameters
Success response (200 OK):
Note: secret is hidden in list and show responses. It is only returned when the webhook is first created or the secret is regenerated.

GET /2023-11/admin/webhooks/count

Return the total number of webhooks for the current company.
Success response (200 OK):

POST /2023-11/admin/webhooks

Create a new webhook. The signing secret (32 random characters) is generated automatically and included in the response once only. Request body
Success response (201 Created):
Error responses
  • 422{ "message": "The given data was invalid.", "errors": { "url": ["The URL must use the HTTPS protocol"], "events": ["At least one event must be selected"] } }

GET /2023-11/admin/webhooks/{webhook}

Get a single webhook. Path parameters Success response (200 OK): Webhook resource (secret hidden).
Error responses
  • 404{ "message": "Webhook not found" }

PUT /2023-11/admin/webhooks/{webhook}

Update a webhook’s URL, events, description, or active state. Path parameters Request body
Success response (200 OK): Updated webhook resource.
Error responses
  • 404{ "message": "Webhook not found" }
  • 422 — validation errors

DELETE /2023-11/admin/webhooks/{webhook}

Delete (soft-delete) a webhook. Path parameters Success response (200 OK): Deleted webhook resource.
Error responses
  • 404{ "message": "Webhook not found" }

PATCH /2023-11/admin/webhooks/{webhook}/toggle

Toggle the is_active flag on a webhook. Also resets the failure_count to 0. Path parameters Request body: None — no body required for this action endpoint.
Success response (200 OK): Updated webhook resource with toggled is_active.
Error responses
  • 404{ "message": "Webhook not found" }

POST /2023-11/admin/webhooks/{webhook}/test

Send a test event payload to the webhook URL. Useful for verifying connectivity. Path parameters Request body: None — the test payload is constructed automatically from the stored webhook record (id, company_id, secret).
Success response (200 OK):
The test payload sent to your endpoint:
Error responses
  • 404{ "message": "Webhook not found" }
  • 500{ "message": "Error sending test webhook", "error": "..." }

PATCH /2023-11/admin/webhooks/{webhook}/regenerate-secret

Generate a new signing secret for the webhook. Resets failure_count to 0. The new secret is returned in the response — update your HMAC verification logic accordingly. Path parameters Request body: None — no body required for this action endpoint.
Success response (200 OK): Webhook resource with new secret visible.

Payment Methods

GET /2023-11/developer/payment-methods

List payment methods for the company. Query parameters
Success response (200 OK): Paginated list of payment method objects.

POST /2023-11/developer/payment-methods

Create a new payment method (or update the existing one for the same processor). Also creates a linked treasury account if none exists. Request body
Success response (201 Created): Payment method resource.
Error responses
  • 400{ "message": "Invalid payment processor" }
  • 500{ "message": "An error occurred while creating the payment method" }

GET /2023-11/developer/payment-methods/{paymentMethod}

Get a single payment method. Path parameters Success response (200 OK): Payment method resource.

PUT /2023-11/developer/payment-methods/{paymentMethod}

Update a payment method’s account_id, status, metadata, and configurations. Path parameters Request body Success response (200 OK): Updated payment method resource.

DELETE /2023-11/developer/payment-methods/{paymentMethod}

Delete a payment method. Path parameters Success response (204 No Content): Empty body.

GET /2023-11/developer/payment-methods/stripe/connect

Initiate Stripe Connect OAuth. Returns the Stripe OAuth authorization URL the user should be redirected to.
Success response (200 OK):

POST /2023-11/developer/payment-methods/stripe/direct-keys

Save direct Stripe integration keys (publishable key, secret key, webhook signing secret). Validates the secret key against Stripe before saving. Switches the integration mode to direct. Request body
Success response (200 OK):
Error responses
  • 422{ "message": "Invalid Stripe secret key." }
  • 422{ "message": "Could not validate Stripe credentials: ..." }

GET /2023-11/developer/payment-methods/stripe/webhook-url

Get the Stripe webhook endpoint URL to register in the Stripe dashboard for direct-mode merchants.
Success response (200 OK):
If no Stripe payment method is configured:

File Uploads (S3)

Genuka uses a two-step upload pattern: first obtain a presigned URL, then PUT directly to S3. For large files, use the multipart flow.

POST /2023-11/developer/upload/presign

Generate a presigned S3 PUT URL for single-file upload. Request body
Success response (200 OK):
After upload: pass key in the medias[].s3_key field when creating or updating the model.

POST /2023-11/developer/upload/multipart/create

Create a multipart upload and get presigned URLs for all parts. Request body
Success response (200 OK):

POST /2023-11/developer/upload/multipart/complete

Complete a multipart upload after all parts have been PUT to S3. Request body
Success response (200 OK): S3 CompleteMultipartUpload result.

POST /2023-11/developer/upload/multipart/abort

Abort an in-progress multipart upload. Request body
Success response (200 OK):

DELETE /2023-11/developer/upload/by-key

Delete an S3 object by its key. Only keys under company/{companyId}/ are permitted. Request body
Success response (200 OK):
Error responses
  • 403{ "message": "Unauthorized key prefix" }

Wallets & Withdrawals

GET /2023-11/developer/wallets

List wallet transaction ledger entries for the developer’s company. Query parameters
Success response (200 OK): Paginated wallet entries.
Error responses
  • 422{ "message": "User is not linked to any company." }

POST /2023-11/developer/withdraw

Submit a withdrawal request against the company wallet balance. Only one pending request is allowed at a time. Request body
Success response (201 Created):
Error responses
  • 422{ "message": "Insufficient wallet balance." }
  • 422{ "message": "You already have a withdraw request in progress." }

GET /2023-11/developer/withdraw/withdraw-requests

List all withdrawal requests for the developer’s company. Query parameters
Success response (200 OK): Paginated withdraw requests.
Possible status values: pending, approved, rejected.