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

# Authorize intent

After an intent is proposed, it must be authorized before Privy executes it. Each eligible owner or signer authorizes the intent by adding an **authorization signature**. Signatures can be added independently, over time, until the resource's authorization threshold is met.

## Authorize an intent

To authorize an intent, submit an authorization signature to the authorize endpoint:

```sh theme={"system"}
POST https://api.privy.io/v1/intents/{intent_id}/authorize
```

The endpoint can be called with your app secret or with a wallet owner's user token, and accepts an object with the following fields:

<ParamField body="signature" type="string" required>
  An [authorization signature](/api-reference/authorization-signatures) over the intent's action.
</ParamField>

<ParamField body="timestamp" type="number" required>
  Unix timestamp, in milliseconds, when the signature was created. Privy uses it to verify the
  signing key was valid at signing time.
</ParamField>

<Tabs>
  <Tab title="REST API">
    ```bash theme={"system"}
    curl -X POST https://api.privy.io/v1/intents/<intent_id>/authorize \
      -u "<your-privy-app-id>:<your-privy-app-secret>" \
      -H "privy-app-id: <your-privy-app-id>" \
      -H "Content-Type: application/json" \
      -d '{
        "signature": "<authorization-signature>",
        "timestamp": 1741834854578
      }'
    ```
  </Tab>

  <Tab title="Java SDK">
    ```java theme={"system"}
    import io.privy.api.PrivyClient;
    import io.privy.api.models.components.AuthorizationContext;
    import io.privy.api.models.operations.IntentAuthorizeResponse;
    import java.util.Arrays;

    PrivyClient client = PrivyClient.builder()
        .appId("your-privy-app-id")
        .appSecret("your-app-secret")
        .build();

    // The authorize endpoint accepts a single signature, so include exactly one signing mechanism.
    AuthorizationContext authorizationContext = AuthorizationContext.builder()
        .addAuthorizationPrivateKeys(Arrays.asList("your-authorization-private-key"))
        .build();

    // Fetches the intent, builds and signs the authorization payload, and submits it.
    IntentAuthorizeResponse response = client.intents().authorize("insert-intent-id", authorizationContext);
    ```
  </Tab>
</Tabs>

The `signature` is an [authorization signature](/api-reference/authorization-signatures) over the intent's underlying request. Generate it with the resource owner's authorization key, following the [signing guides](/controls/authorization-keys/using-owners/sign/overview).

<Tip>
  The authorize endpoint accepts a single signature per call. To satisfy a threshold greater than
  one, each owner or signer calls the endpoint with their own signature.
</Tip>

## Execution

When authorizations meet the resource's authorization threshold, Privy executes the action automatically. The intent moves from **Pending** to **Processing** for asynchronous actions such as transfers, and then to **Executed** or **Failed**.

Retrieve the outcome by [fetching the intent](/transaction-management/intents/fetch-intent) or by listening to the `intent.executed` webhook. For transaction intents, the `action_result` field contains the transaction hash. See [intent status](/transaction-management/intents/lifecycle) for details on each status.

## Idempotency

Privy records one authorization per signer. Re-submitting the same signer's authorization is safe: it does not add a duplicate approval or advance the intent past its threshold more than once, and the action executes only once when the threshold is met.

## Errors

Authorizing an intent returns an error in the following cases:

| Condition               | Description                                                                                                   |
| ----------------------- | ------------------------------------------------------------------------------------------------------------- |
| Intent not found        | No intent matches the provided `intent_id`.                                                                   |
| Intent not authorizable | The intent is already **Executed**, **Failed**, **Rejected**, **Expired**, **Dismissed**, or **Processing**.  |
| Invalid signature       | The `signature` is malformed, or the `timestamp` falls outside the window in which the signing key was valid. |
| Ineligible signer       | The signer is not an owner or signer eligible to authorize this intent.                                       |

## Next steps

<CardGroup cols={2}>
  <Card title="Propose intents" icon="paper-plane" href="/transaction-management/intents/create/execute-transfer">
    Propose an intent to transfer funds, run a transaction, or update a resource.
  </Card>

  <Card title="Intent status" icon="arrows-spin" href="/transaction-management/intents/lifecycle">
    Track an intent from proposal to execution.
  </Card>
</CardGroup>
