> ## Documentation Index
> Fetch the complete documentation index at: https://docs.salesive.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Code-first declarations

> Declare your app's scopes, storefront extensions, dashboard extensions and workflow steps from its own code with its OAuth client credentials. The developer console displays them read-only.

Your app's code is the source of truth for what it declares. Instead of pasting
JSON into the developer console, your server pushes its scopes, extensions and
workflow steps through one endpoint, authenticated with the same OAuth client
credentials it uses for token requests. The console then displays them, the
same way it displays your registered tools: a view of what the code declares,
not a second place to edit it.

```http theme={null}
PUT https://api.salesive.com/api/v1/app/declarations
Content-Type: application/json

{
  "clientId": "app_xxxxxxxxxxxxxxxx",
  "clientSecret": "sk_xxxxxxxxxxxxxxxx",
  "scopes": ["READ_ORDERS", "WRITE_WORKFLOW_TRIGGERS"],
  "extensions": {
    "embeds": [{ "key": "chat", "scriptUrl": "https://cdn.example.com/chat.js" }],
    "blocks": [{ "key": "review-stars", "scriptUrl": "https://cdn.example.com/stars.js" }]
  },
  "dashboardExtensions": [
    { "target": "order.details.block", "label": "Fraud score", "path": "/ext/fraud" }
  ],
  "workflow": { "actions": [], "triggers": [] }
}
```

Every field is optional; anything you do not send keeps its current value. The
four keys a declaration may carry are `scopes`, `extensions`,
`dashboardExtensions` and `workflow`, nothing else; listing fields (name,
icons, URLs) stay with the console.

`GET /api/v1/app/declarations` with the same credentials reads the current
declarations back, so a startup script can diff before it writes.

## Authentication

Send your `clientId` and `clientSecret` in the body, or as a Basic auth
header (`clientId:clientSecret`). The secret is required, so a leaked client id
alone does nothing. This is the same pair your server already holds for token
requests.

## What is validated

Exactly what the console would validate, because both paths run the same code:

* `scopes` must come from the grantable list; unknown entries are dropped.
* `extensions` embeds and blocks: https URLs, valid keys, per-list caps.
* `dashboardExtensions`: one of the twelve targets, label 1 to 40 characters,
  a path inside your app, heights within the kind's limits.
* `workflow` actions and triggers: full schema validation, and actions need a
  webhook URL set before they can be declared.

A validation problem answers `400` with the field that failed, the same
message the console would show.

## When to call it

* On startup or deploy, so the console always matches the code (idempotent:
  sending the same declaration again changes nothing).
* After you add a scope, extension kind or workflow step to your code.

Scopes you declare are what new installs ask for on the consent screen. An
installed store keeps its granted scopes until the merchant reconnects; only
then does the new scope take effect for that store.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.