> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.jelliu.co/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.jelliu.co/_mcp/server.

# Approve a held agent action (and execute it)

POST https://api.jelliu.co/api/agent-approvals/{id}/approve
Content-Type: application/json

Approves one write an agent asked for and the workspace's approval policy held for review
(`GET /api/agent-approvals` lists them). **By default approving executes the action**, exactly
once, with the exact arguments the agent sent, and the response carries the real outcome.
Send `"execute": false` to approve it without executing — the decision is recorded and a
person does it by hand.

**Payments held by the platform.** When a payment is confirmed (a Cobre or dLocal charge paid,
or a payment receipt confirmed by a bank credit or verified by a person), Jelliu holds one action
per connected ERP to register it (`tool_source: erp_payment`, `origin: system`, requested by
"Jelliu", valid for 7 days). These are never executed without approval. Approving one creates
the payment exactly as shown (Alegra payment or Siigo cash receipt, applied to the matched open
invoice), after re-checking that the ERP is still connected and that the invoice still belongs to
that customer and still owes at least the amount. When the customer, the invoice or where the
money landed could not be determined unambiguously (and always for SAP Business One), the action
is held record-only: `executable` is `false`, its `params.motivo` says why, executing it answers
`409 AGENT_ACTION_NOT_EXECUTABLE`, and it is approved with `"execute": false` once registered by hand.

**What is checked again at execution time.** The approval authorizes this action; it does not
bypass anything else. Before sending it, every control the agent's own write would pass is
re-checked: the app is still connected (and to the same account the request was made against),
the agent is not paused or deleted, the app is still in the agent's scope and not read-only,
the tool is not disabled, the write lane is on, and the month's execution budget is not spent.
If any of these changed, nothing is sent and the action ends in `execution_failed` with the
reason.

**Outcomes** (`status` in the response and on the row):
- `executed` — it ran and the app confirmed it. `executedAt` and `executionActionId` (the
  agent action log entry for the execution) are set.
- `execution_failed` — it definitely did not happen: a control refused it or the app rejected
  it. `executionError` says why.
- `execution_unknown` — it was sent but the answer was lost (timeout, network). It may or may
  not have happened; check the app before doing it again. It is never retried automatically.
- `approved` — only with `"execute": false`: recorded, nothing executed.

The workspace also gets an in-app notification with the outcome.

**Idempotency.** Exactly once. Two concurrent approvals of the same action execute it a single
time; the other request gets `409 AGENT_ACTION_APPROVAL_CLOSED` naming the state and who
decided it. An expired action is never executed. Do not retry a `200` whose `status` is
`execution_unknown`: the action cannot be approved twice, by design.

**Access**
- **Required role:** `admin` (a person, or a key with `full` scope). An agent key can never
  approve its own action.
- **Rate limit:** Audit routes limit. See [Rate limits](/rate-limits).
- **Plan:** Available on every plan.


Reference: https://developer.jelliu.co/api-reference/agents/post-agent-approvals-by-id-approve

## Authentication

- `Authorization` header (bearer token, required) — Workspace API key: `jl_` followed by 64 lowercase hex characters, created by the workspace owner in the dashboard (**Settings → API Keys**) and sent as `Authorization: Bearer jl_...`. The plaintext is shown once, at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys. | Scope | GET / HEAD | POST / PUT / PATCH / DELETE | Admin-only routes | | --- | --- | --- | --- | | `read` | Yes | No | No | | `write` | Yes | Yes | No | | `full` | Yes | Yes | Yes | Operations restricted to admins or owners reject keys without the `full` scope with `403`, and say so in their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret — that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds. See [Authentication](/authentication).

## Request

### Path parameters

- `id` (string, required) — UUID of the held action.

### Body (application/json)

This endpoint expects an object.

- `note` (string, optional) — Optional note from the approver, stored with the decision.
- `execute` (boolean, optional, default: true) — `true` (default) executes the action once. `false` approves it without executing (record-only). Must be a JSON boolean; a string is rejected with `400`.

## Response

### 200

The approval was recorded. `executed` and `status` say what happened to the action; a `200` does not by itself mean the action ran.

- `data` (ApiAgentApprovalsIdApprovePostResponsesContentApplicationJsonSchemaData, required)

## Errors

### 400 Bad Request Error

`id` is not a UUID, or the body is invalid (for example `execute` is not a boolean).

- `error` (ErrorResponseError, required) — The error object. Always has `code` and `message`.

### 401 Unauthorized Error

No usable credential. Either the `Authorization` header is missing or is not a well-formed `Bearer jl_…` key, or the key is unknown, revoked or expired. Do not retry with the same key. See [Authentication](/authentication#401-unauthorized).

- `error` (ErrorResponseError, required) — The error object. Always has `code` and `message`.

### 403 Forbidden Error

Authenticated, but not allowed: the key's scope does not cover the method, the route is restricted to workspace admins/owners and the key is not `full`, or the workspace is suspended (`TENANT_SUSPENDED`). See [Authentication](/authentication#scopes).

- `error` (ErrorResponseError, required) — The error object. Always has `code` and `message`.

### 404 Not Found Error

No held action with this id in the workspace.

- `error` (ErrorResponseError, required) — The error object. Always has `code` and `message`.

### 409 Conflict Error

Nothing changed. `AGENT_ACTION_APPROVAL_CLOSED`: the action expired, was already decided, or is being executed by another approval (`metadata.status` says which). `AGENT_ACTION_NOT_EXECUTABLE`: the action was held without what is needed to execute it; approve it with `"execute": false` and do it by hand.

- `error` (ErrorResponseError, required) — The error object. Always has `code` and `message`.

### 429 Too Many Requests Error

Rate limit exceeded for the current 60-second window (`RATE_LIMIT_EXCEEDED`). Wait `Retry-After` seconds, then retry. The `message` differs per limiter; the code does not. See [Rate limits](/rate-limits).

- `error` (ErrorResponseError, required) — The error object. Always has `code` and `message`.

## Types

### ApiAgentApprovalsIdApprovePostResponsesContentApplicationJsonSchemaData

- `id` (string, required)
- `status` (enum, required)
  - Allowed values: `executed`, `execution_failed`, `execution_unknown`, `approved`
- `toolName` (string, required)
- `decidedAt` (datetime, required)
- `executed` (boolean, required) — True only when the app confirmed the write.
- `message` (string, required) — A sentence for the dashboard, in Spanish.
- `executedAt` (datetime, optional, nullable)
- `executionActionId` (string, optional, nullable) — The agent action log entry written for the execution attempt.
- `executionError` (string, optional, nullable) — Why it did not run, or why its outcome is unknown.

### ErrorResponseError

The error object. Always has `code` and `message`.

- `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `PAYLOAD_TOO_LARGE`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
- `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
- `details` (ErrorResponseErrorDetails, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields); * for a rejected multipart upload (file in an unexpected field, too many files), a list with the upload error `code` (for example `LIMIT_UNEXPECTED_FILE`) and the `field` name. Absent when the value was rejected outside the route's own validation: a malformed id, number or date the database could not read, or a JSON body that does not parse.
- `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps), `tier` alone (feature gates), or `tier` = `none` with `kind` = `subscription_required` when the workspace has no active subscription. See [Errors](/errors).

### ErrorResponseErrorDetails

Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields); * for a rejected multipart upload (file in an unexpected field, too many files), a list with the upload error `code` (for example `LIMIT_UNEXPECTED_FILE`) and the `field` name. Absent when the value was rejected outside the route's own validation: a malformed id, number or date the database could not read, or a JSON body that does not parse.

- Field map: Field map
- Issue list: list of ErrorResponseErrorDetailsOneOf1Items

### Field map

- `formErrors` (list of string, optional)
- `fieldErrors` (map from string to list of string, optional)

### ErrorResponseErrorDetailsOneOf1Items

- `path` (ErrorResponseErrorDetailsOneOf1ItemsPath, optional) — Dot-separated string, or an array of keys.
- `message` (string, optional)
- `code` (string, optional) — Zod issue code, for example `invalid_type`.

### ErrorResponseErrorDetailsOneOf1ItemsPath

Dot-separated string, or an array of keys.

- string
- list of ErrorResponseErrorDetailsOneOf1ItemsPathOneOf1Items

### ErrorResponseErrorDetailsOneOf1ItemsPathOneOf1Items

- string
- integer

## Examples

### Executed

**Response**

```json
{
  "data": {
    "id": "3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c",
    "status": "executed",
    "toolName": "HUBSPOT_CREATE_NOTE",
    "decidedAt": "2026-09-22T15:04:05Z",
    "executed": true,
    "message": "Aprobada y ejecutada: la acción ya se aplicó.",
    "executedAt": "2026-09-22T15:04:06Z",
    "executionActionId": "8b1c2d3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
    "executionError": null
  }
}
```

**SDK Code**

```python Executed
import requests

url = "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript Executed
const url = 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Executed
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Executed
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java Executed
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Executed
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp Executed
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Executed
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Approved, but a control refused it at execution time

**Response**

```json
{
  "data": {
    "id": "3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c",
    "status": "execution_failed",
    "toolName": "HUBSPOT_CREATE_NOTE",
    "decidedAt": "2026-09-22T15:04:05Z",
    "executed": false,
    "message": "Aprobada, pero no se ejecutó: La conexión de hubspot ya no está activa en este workspace, así que la acción no se ejecutó.",
    "executedAt": null,
    "executionActionId": "8b1c2d3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
    "executionError": "La conexión de hubspot ya no está activa en este workspace, así que la acción no se ejecutó."
  }
}
```

**SDK Code**

```python Approved, but a control refused it at execution time
import requests

url = "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript Approved, but a control refused it at execution time
const url = 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Approved, but a control refused it at execution time
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Approved, but a control refused it at execution time
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java Approved, but a control refused it at execution time
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Approved, but a control refused it at execution time
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp Approved, but a control refused it at execution time
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Approved, but a control refused it at execution time
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Approved without executing

**Response**

```json
{
  "data": {
    "id": "3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c",
    "status": "approved",
    "toolName": "HUBSPOT_CREATE_NOTE",
    "decidedAt": "2026-09-22T15:04:05Z",
    "executed": false,
    "message": "Aprobada sin ejecutar: queda registrada y hay que hacerla a mano.",
    "executedAt": null,
    "executionActionId": null,
    "executionError": null
  }
}
```

**SDK Code**

```python Approved without executing
import requests

url = "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript Approved without executing
const url = 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Approved without executing
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Approved without executing
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java Approved without executing
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Approved without executing
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp Approved without executing
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Approved without executing
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Approve and execute

**Request**

```json
{
  "note": "Revisado con el cliente"
}
```

**Response**

```json
{
  "data": {
    "id": "3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c",
    "status": "executed",
    "toolName": "HUBSPOT_CREATE_NOTE",
    "decidedAt": "2026-09-22T15:04:05Z",
    "executed": true,
    "message": "Aprobada y ejecutada: la acción ya se aplicó.",
    "executedAt": "2026-09-22T15:04:06Z",
    "executionActionId": "8b1c2d3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
    "executionError": null
  }
}
```

**SDK Code**

```python Approve and execute
import requests

url = "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

payload = { "note": "Revisado con el cliente" }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Approve and execute
const url = 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"note":"Revisado con el cliente"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Approve and execute
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

	payload := strings.NewReader("{\n  \"note\": \"Revisado con el cliente\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Approve and execute
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"note\": \"Revisado con el cliente\"\n}"

response = http.request(request)
puts response.read_body
```

```java Approve and execute
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"note\": \"Revisado con el cliente\"\n}")
  .asString();
```

```php Approve and execute
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve', [
  'body' => '{
  "note": "Revisado con el cliente"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Approve and execute
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"note\": \"Revisado con el cliente\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Approve and execute
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["note": "Revisado con el cliente"] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Approve without executing

**Request**

```json
{
  "note": "Lo hago yo a mano",
  "execute": false
}
```

**Response**

```json
{
  "data": {
    "id": "3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c",
    "status": "executed",
    "toolName": "HUBSPOT_CREATE_NOTE",
    "decidedAt": "2026-09-22T15:04:05Z",
    "executed": true,
    "message": "Aprobada y ejecutada: la acción ya se aplicó.",
    "executedAt": "2026-09-22T15:04:06Z",
    "executionActionId": "8b1c2d3e-4f5a-4b6c-8d7e-9f0a1b2c3d4e",
    "executionError": null
  }
}
```

**SDK Code**

```python Approve without executing
import requests

url = "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

payload = {
    "note": "Lo hago yo a mano",
    "execute": False
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Approve without executing
const url = 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"note":"Lo hago yo a mano","execute":false}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Approve without executing
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve"

	payload := strings.NewReader("{\n  \"note\": \"Lo hago yo a mano\",\n  \"execute\": false\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Approve without executing
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"note\": \"Lo hago yo a mano\",\n  \"execute\": false\n}"

response = http.request(request)
puts response.read_body
```

```java Approve without executing
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"note\": \"Lo hago yo a mano\",\n  \"execute\": false\n}")
  .asString();
```

```php Approve without executing
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve', [
  'body' => '{
  "note": "Lo hago yo a mano",
  "execute": false
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Approve without executing
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"note\": \"Lo hago yo a mano\",\n  \"execute\": false\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Approve without executing
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "note": "Lo hago yo a mano",
  "execute": false
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/agent-approvals/3f2a9c1e-5b7d-4e8a-9c6b-1d2e3f4a5b6c/approve")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```