> This page is for version 2025-09-18 (default).
> For other versions, use one of these documentation indexes:
> - 2025-09-18 (default): https://apidocs.polytomic.com/2025-09-18/llms.txt
> - 2024-02-08: https://apidocs.polytomic.com/2024-02-08/llms.txt
> - 2023-04-25: https://apidocs.polytomic.com/2023-04-25/llms.txt
> - 2022-12-12: https://apidocs.polytomic.com/2022-12-12/llms.txt
> - 2021-05-23: https://apidocs.polytomic.com/2021-05-23/llms.txt

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

# Execute Harbor Action

POST https://app.polytomic.com/api/harbors/{harbor_id}/actions/execute
Content-Type: application/json

Execute a prepared action with at most one application attempt per server-issued execution identifier.

First call [Prepare action](../../../../../api-reference/harbors/actions/prepare). Submit only
its server-issued `execution_id` using a writable scoped credential belonging to
the same Harbor. The destination, operation, lookup, and input are fixed by
preparation. No per-request approval is required.

Polytomic checks current grants, provider capabilities, and the saved Connection
again before execution. Preparation does not reserve permission. An expired
preparation cannot start an execution. It returns `410 Gone` while the expired
preparation remains available, or `404 Not Found` after cleanup.

> 🚧 Updates can overwrite intervening edits
>
> Enabled operations can act on records accessible through the saved Connection
> and may trigger provider automation. Preparation does not lock the destination
> record. Action permission does not grant read access.

## One intended attempt

An identifier already claimed for execution returns its original receipt,
including through another eligible credential or after action disablement.
Receipts remain available after prepared arguments are removed or expire.
They are retained independently of Activity history.

An `action.attempt_started` event means permission to attempt the action was
claimed, not that the provider received it. Disabling actions blocks new claims
but does not recall an accepted attempt. This is at most one application attempt
per execution identifier, not a remote exactly-once guarantee. Advertised remote
idempotency does not authorize automatic replay.

## Results and recovery

Keep `execution_id` and the returned `status_path`. `succeeded` means the provider
confirmed the operation and Polytomic recorded that outcome. `failed` means the
operation was rejected. `executing` is incomplete. `recovery_required: true`
does not confirm durable acceptance or completion. Use the status path after a
timeout or server error. A missing receipt does not prove no operation occurred.

> ⚠️ An unknown outcome is terminal
>
> `unknown` means the operation may have happened. Investigate the record and
> provider automation. Do not resubmit or prepare a replacement action to retry.
> Polytomic never automatically retries an uncertain attempt. An overdue
> executing receipt becomes unknown after its 90-second deadline.

Send a separate nonzero UUID in `X-Polytomic-Activity-Request-ID` for each HTTP
request. MCP supplies this transport header automatically.
`X-Polytomic-Harbor-Session` is optional for direct REST requests; a supplied
session must be active and bound to your credential and Harbor. Receipts and
Activity contain operation identity, lookup field names, submitted field names,
original attribution, and safe outcome categories. They exclude lookup values,
input values, output payloads, and raw provider errors.

Reference: https://apidocs.polytomic.com/api-reference/harbors/actions/execute

## Authentication

- `Authorization` header (bearer token, required) — Bearer user API key
- `Authorization` header (basic auth, required) — Basic organization-scoped API key

## Request

### Path parameters

- `harbor_id` (string, required) — Unique identifier of the Harbor

### Headers

- `X-Polytomic-Harbor-Session` (string, optional) — Harbor session token; when supplied, the session must be active and bound to this credential and Harbor.
- `X-Polytomic-Activity-Request-ID` (string, optional) — New nonzero UUID for each request, required for scoped credentials; a reused value is rejected.

### Body (application/json)

This endpoint expects an ExecuteHarborActionRequest.

- `execution_id` (string, required) — Server-issued identifier returned by prepare. Preserve it for status recovery; never prepare a replacement to retry uncertainty.

## Response

### 200

OK

- `data` (HarborActionExecutionResponse, optional) — The execution receipt

## Types

### HarborActionExecutionResponse

- `connection_id` (string, optional) — Connection ID of the action
- `credential_id` (string, optional) — Original credential attribution, including when another credential submits a duplicate
- `deadline_at` (datetime, optional) — When an unfinished execution becomes unknown
- `execution_id` (string, optional) — Action execution ID
- `failure_category` (string, optional) — Category of a failed or unknown outcome
- `field_ids` (list of string, optional, nullable) — Submitted field names only, never their values
- `finished_at` (datetime, optional, nullable) — When the execution reached its final status
- `lookup_field_id` (string, optional) — Lookup field ID used to find the target record
- `operation_id` (string, optional) — Operation ID of the action
- `recovery_required` (boolean, optional) — True when receipt persistence was interrupted or uncertain. Inspect status; this response does not confirm durable acceptance or completion.
- `schema_id` (string, optional) — Schema ID of the action
- `started_at` (datetime, optional) — When the execution started
- `status` (enum, optional) — Current execution status
  - Allowed values: `executing`, `succeeded`, `failed`, `unknown`
- `status_path` (string, optional) — API path for reading this execution receipt

## Examples

**Request**

```json
{
  "execution_id": "248df4b7-aa70-47b8-a036-33ac447e668d"
}
```

**Response**

```json
{
  "data": {
    "connection_id": "248df4b7-aa70-47b8-a036-33ac447e668d",
    "credential_id": "248df4b7-aa70-47b8-a036-33ac447e668d",
    "deadline_at": "2024-01-15T09:30:00Z",
    "execution_id": "248df4b7-aa70-47b8-a036-33ac447e668d",
    "failure_category": "string",
    "field_ids": [
      "string"
    ],
    "finished_at": "2024-01-15T09:30:00Z",
    "lookup_field_id": "string",
    "operation_id": "string",
    "recovery_required": true,
    "schema_id": "string",
    "started_at": "2024-01-15T09:30:00Z",
    "status": "executing",
    "status_path": "string"
  }
}
```

**SDK Code**

```python
import requests

url = "https://app.polytomic.com/api/harbors/248df4b7-aa70-47b8-a036-33ac447e668d/actions/execute"

payload = { "execution_id": "248df4b7-aa70-47b8-a036-33ac447e668d" }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript
const url = 'https://app.polytomic.com/api/harbors/248df4b7-aa70-47b8-a036-33ac447e668d/actions/execute';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"execution_id":"248df4b7-aa70-47b8-a036-33ac447e668d"}'
};

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

```go
package main

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

func main() {

	url := "https://app.polytomic.com/api/harbors/248df4b7-aa70-47b8-a036-33ac447e668d/actions/execute"

	payload := strings.NewReader("{\n  \"execution_id\": \"248df4b7-aa70-47b8-a036-33ac447e668d\"\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
require 'uri'
require 'net/http'

url = URI("https://app.polytomic.com/api/harbors/248df4b7-aa70-47b8-a036-33ac447e668d/actions/execute")

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  \"execution_id\": \"248df4b7-aa70-47b8-a036-33ac447e668d\"\n}"

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

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

HttpResponse<String> response = Unirest.post("https://app.polytomic.com/api/harbors/248df4b7-aa70-47b8-a036-33ac447e668d/actions/execute")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"execution_id\": \"248df4b7-aa70-47b8-a036-33ac447e668d\"\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://app.polytomic.com/api/harbors/248df4b7-aa70-47b8-a036-33ac447e668d/actions/execute', [
  'body' => '{
  "execution_id": "248df4b7-aa70-47b8-a036-33ac447e668d"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://app.polytomic.com/api/harbors/248df4b7-aa70-47b8-a036-33ac447e668d/actions/execute");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"execution_id\": \"248df4b7-aa70-47b8-a036-33ac447e668d\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["execution_id": "248df4b7-aa70-47b8-a036-33ac447e668d"] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://app.polytomic.com/api/harbors/248df4b7-aa70-47b8-a036-33ac447e668d/actions/execute")! 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()
```