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

# Change Transaction Status

> Update transaction status and trigger update rules automatically — in the gu1 transaction monitoring product for fraud and AML, with examples for change status.

## Endpoint

### Change Transaction Status

```
PATCH http://api.gu1.ai/transactions/:id/changeStatus
```

Updates the status of an existing transaction with automatic validation of state transitions and optional rule execution for real-time risk re-assessment.

**Features:**

* Automatic validation of status transitions (prevents invalid state changes)
* State machine enforcement (open ↔ closed state rules)
* Automatic execution of rules/matrices with **`transaction_status_changed`** trigger (not `transaction_updated`)
* Transaction integrity protection
* Comprehensive audit trail

## Authentication

All requests must include an API key in the `Authorization` header:

```bash theme={null}
Authorization: Bearer YOUR_API_KEY
```

## Required Headers

```bash theme={null}
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
```

## Path Parameters

<ParamField path="id" type="string" required>
  The UUID of the transaction to update

  **Type**: `string` (uuid)
</ParamField>

## Request Body

<ParamField body="status" type="string" required>
  New transaction status. Must be a valid status enum value.

  **Valid Statuses**:

  * `CREATED` - Transaction created (open state)
  * `PROCESSING` - Transaction being processed (open state)
  * `SUSPENDED` - Transaction temporarily suspended (open state)
  * `SENT` - Transaction sent/transmitted (closed state)
  * `EXPIRED` - Transaction expired (closed state)
  * `DECLINED` - Transaction declined/rejected (closed state)
  * `REFUNDED` - Transaction refunded/reversed (closed state)
  * `SUCCESSFUL` - Transaction completed successfully (closed state)

  **Type**: `enum` - `'CREATED' | 'PROCESSING' | 'SUSPENDED' | 'SENT' | 'EXPIRED' | 'DECLINED' | 'REFUNDED' | 'SUCCESSFUL'`
</ParamField>

## State Transition Rules

The endpoint enforces strict state transition rules to maintain transaction integrity:

### Open States

States that allow further transitions:

* `CREATED`
* `PROCESSING`
* `SUSPENDED`
* `SENT`

### Closed States

Final states that **cannot** transition to other states:

* `EXPIRED`
* `DECLINED`
* `REFUNDED`
* `SUCCESSFUL`

### Transition Matrix

| From State     | To State   | Allowed? | Note                                |
| -------------- | ---------- | -------- | ----------------------------------- |
| CREATED        | PROCESSING | ✅ Yes    | Normal flow                         |
| CREATED        | SUSPENDED  | ✅ Yes    | Suspend for review                  |
| CREATED        | SUCCESSFUL | ✅ Yes    | Quick approval                      |
| PROCESSING     | SUSPENDED  | ✅ Yes    | Suspend during processing           |
| PROCESSING     | SUCCESSFUL | ✅ Yes    | Normal completion                   |
| PROCESSING     | DECLINED   | ✅ Yes    | Reject during processing            |
| SUSPENDED      | PROCESSING | ✅ Yes    | Resume processing                   |
| SUSPENDED      | SUCCESSFUL | ✅ Yes    | Approve suspended transaction       |
| SUSPENDED      | DECLINED   | ✅ Yes    | Reject suspended transaction        |
| **SUCCESSFUL** | PROCESSING | ❌ No     | Cannot reopen closed transaction    |
| **DECLINED**   | PROCESSING | ❌ No     | Cannot reopen closed transaction    |
| **EXPIRED**    | PROCESSING | ❌ No     | Cannot reopen closed transaction    |
| **REFUNDED**   | any        | ❌ No     | Cannot change refunded transaction  |
| **SUCCESSFUL** | DECLINED   | ❌ No     | Cannot change between closed states |

**Key Rules**:

1. ✅ **Open → Open**: Allowed (e.g., CREATED → PROCESSING)
2. ✅ **Open → Closed**: Allowed (e.g., PROCESSING → SUCCESSFUL)
3. ❌ **Closed → Open**: **NOT** Allowed (e.g., SUCCESSFUL → PROCESSING)
4. ❌ **Closed → Closed**: **NOT** Allowed (e.g., DECLINED → REFUNDED)

## Update Rules Execution

When a transaction status is changed, the endpoint automatically:

1. **Validates the transition** - Ensures the new status is valid and transition is allowed
2. **Updates the status** - Changes the transaction status in the database
3. **Executes status-change rules** - Runs rules/matrices with trigger **`status_changed`** (scope action or matrix `transaction_status_changed`)
4. **Updates risk score** - Re-calculates risk based on rule results
5. **Returns updated transaction** - Returns the complete transaction with new risk assessment

<Note>
  **Distinct from field updates:** `PATCH /transactions/{id}` (metadata, deviceDetails, channel, reason) uses trigger **`updated`**. Only this changeStatus endpoint uses **`status_changed`**. Migrate rules that should run on status transitions to the new trigger.
</Note>

### Rules Trigger

The endpoint uses `trigger_transaction_status_changed`, which executes rules configured with:

* **Loose rules:** `scope.triggers[].event.action = "status_changed"`
* **Risk matrices:** `triggers[].eventType = "transaction_status_changed"`

**Example rule scope configuration**:

```json theme={null}
{
  "scope": {
    "triggers": [
      {
        "type": "event",
        "event": {
          "entityType": "transaction",
          "action": "status_changed",
          "conditions": {}
        }
      }
    ],
    "entityTypes": ["transaction"]
  }
}
```

## Complete Request Examples

### Approve a Suspended Transaction

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH http://api.gu1.ai/transactions/550e8400-e29b-41d4-a716-446655440000/changeStatus \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "status": "SUCCESSFUL"
    }'
  ```

  ```javascript JavaScript theme={null}
  const transactionId = '550e8400-e29b-41d4-a716-446655440000';

  const response = await fetch(`http://api.gu1.ai/transactions/${transactionId}/changeStatus`, {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      status: 'SUCCESSFUL'
    })
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python Python theme={null}
  import requests

  transaction_id = "550e8400-e29b-41d4-a716-446655440000"
  url = f"http://api.gu1.ai/transactions/{transaction_id}/changeStatus"

  headers = {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  payload = {
      "status": "SUCCESSFUL"
  }

  response = requests.patch(url, json=payload, headers=headers)
  result = response.json()

  print(f"Transaction Status: {result['transaction']['status']}")
  summary = result.get("rulesExecutionSummary") or {}
  print(f"Matched rules: {summary.get('matchedRulesCount', 0)}")
  ```
</CodeGroup>

### Decline a Transaction Under Review

<CodeGroup>
  ```bash cURL theme={null}
  curl -X PATCH http://api.gu1.ai/transactions/550e8400-e29b-41d4-a716-446655440000/changeStatus \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "status": "DECLINED"
    }'
  ```

  ```javascript JavaScript theme={null}
  const transactionId = '550e8400-e29b-41d4-a716-446655440000';

  const response = await fetch(`http://api.gu1.ai/transactions/${transactionId}/changeStatus`, {
    method: 'PATCH',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      status: 'DECLINED'
    })
  });

  const result = await response.json();
  console.log(result);
  ```

  ```python Python theme={null}
  import requests

  transaction_id = "550e8400-e29b-41d4-a716-446655440000"
  url = f"http://api.gu1.ai/transactions/{transaction_id}/changeStatus"

  headers = {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json"
  }

  payload = {
      "status": "DECLINED"
  }

  response = requests.patch(url, json=payload, headers=headers)
  result = response.json()

  print(f"Status changed from {result['statusChanged']['from']} to {result['statusChanged']['to']}")
  ```
</CodeGroup>

### Suspend a Transaction for Manual Review

```bash theme={null}
curl -X PATCH http://api.gu1.ai/transactions/550e8400-e29b-41d4-a716-446655440000/changeStatus \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "SUSPENDED"
  }'
```

## Response

### Success Response (200 OK)

```json theme={null}
{
  "success": true,
  "transaction": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "externalId": "txn_12345",
    "type": "PAYMENT",
    "status": "SUCCESSFUL",
    "amount": 1500.00,
    "currency": "USD",
    "amountInUsd": 1500.00,
    "origin": {
      "entityId": "customer_001",
      "externalId": "EXT-001",
      "name": "John Doe",
      "country": "US",
      "details": {},
      "type": "person",
      "riskScore": 15.50
    },
    "destination": {
      "entityId": "merchant_002",
      "externalId": "MER-002",
      "name": "Electronics Store",
      "country": "US",
      "details": {},
      "type": "company",
      "riskScore": 8.20
    },
    "riskScore": 22.50,
    "riskFactors": [
      {
        "factor": "status_change",
        "score": 5,
        "description": "Transaction status changed to SUCCESSFUL"
      }
    ],
    "flagged": false,
    "description": "Laptop purchase",
    "category": "electronics",
    "metadata": {},
    "transactedAt": "2024-12-23T14:30:00.000Z",
    "createdAt": "2024-12-23T14:30:00.000Z",
    "updatedAt": "2024-12-23T15:45:00.000Z"
  },
  "statusChanged": {
    "from": "SUSPENDED",
    "to": "SUCCESSFUL"
  },
  "rulesExecutionSummary": {
    "rulesHit": [
      {
        "name": "High Value Transaction Check",
        "score": 5,
        "status": "active"
      }
    ],
    "rulesNoHit": [],
    "totalScore": 22.5,
    "matchedRulesCount": 3,
    "executionTimeMs": 245,
    "trigger": "status_change"
  }
}
```

### Response Fields

<ResponseField name="success" type="boolean">
  Whether the status change was successful
</ResponseField>

<ResponseField name="transaction" type="object">
  The updated transaction with all its data, including:

  * **id** (string) - Transaction UUID
  * **status** (string) - New transaction status
  * **origin** (object) - Origin party information (nested structure)
    * **entityId** (string) - Origin entity UUID
    * **name** (string) - Origin party name
    * **country** (string) - Origin country
    * **details** (object) - Additional origin details
    * **type** (string) - Origin entity type
    * **riskScore** (number) - Origin entity risk score
  * **destination** (object) - Destination party information (nested structure)
    * **entityId** (string) - Destination entity UUID
    * **name** (string) - Destination party name
    * **country** (string) - Destination country
    * **details** (object) - Additional destination details
    * **type** (string) - Destination entity type
    * **riskScore** (number) - Destination entity risk score
  * **riskScore** (number) - Updated risk score after re-evaluation
  * **riskFactors** (array) - Updated risk factors
  * **flagged** (boolean) - Updated flag status
  * **updatedAt** (string) - Timestamp of the update
</ResponseField>

<ResponseField name="statusChanged" type="object">
  Information about the status transition:

  * **from** (string) - Previous status
  * **to** (string) - New status
</ResponseField>

<ResponseField name="rulesExecutionSummary" type="object">
  **At the root of the response** (aligned with [Create transaction](/en/api-reference/transactions/create)). **Only present when rules ran.** Summary of which rules matched (hit) vs did not match (no hit), executed actions, and total score.

  * **rulesHit** (array) - Rules whose conditions were met. Each item: **name**, **description**, **score**, **priority**, **category**, **status**, **conditions**, **actions**.
  * **rulesNoHit** (array) - Rules evaluated but conditions not met. Same structure as rulesHit.
  * **actionsExecuted** (object) - Aggregated executed actions: **alerts**, **suggestion**, **status**, **assignedUser**, **customKeys** (array of strings, optional) — custom action keys from rules that matched; for integrations/workflows.
  * **totalScore** (number) - Sum of score of all rules that hit (excluding shadow).
</ResponseField>

## Error Responses

### 400 Bad Request - Invalid Status

```json theme={null}
{
  "error": "Invalid status",
  "validStatuses": [
    "CREATED",
    "PROCESSING",
    "SUSPENDED",
    "SENT",
    "EXPIRED",
    "DECLINED",
    "REFUNDED",
    "SUCCESSFUL"
  ]
}
```

### 400 Bad Request - Invalid Transition

```json theme={null}
{
  "error": "Cannot transition from closed status to open status",
  "currentStatus": "SUCCESSFUL",
  "requestedStatus": "PROCESSING",
  "message": "Transaction is in a closed state (SUCCESSFUL) and cannot be reopened"
}
```

### 404 Not Found

```json theme={null}
{
  "error": "Transaction not found"
}
```

### 401 Unauthorized

```json theme={null}
{
  "error": "Unauthorized",
  "message": "Invalid or missing API key"
}
```

### 500 Internal Server Error

```json theme={null}
{
  "error": "Failed to change transaction status",
  "details": "Internal server error message"
}
```

## Use Cases

### 1. Manual Review Workflow

```javascript theme={null}
// Step 1: Suspend suspicious transaction
await changeStatus(transactionId, 'SUSPENDED');

// Step 2: Analyst reviews transaction
// ... manual review process ...

// Step 3: Approve or decline based on review
if (approved) {
  await changeStatus(transactionId, 'SUCCESSFUL');
} else {
  await changeStatus(transactionId, 'DECLINED');
}
```

### 2. Automated Compliance Check

```javascript theme={null}
// Transaction created with CREATED status
const transaction = await createTransaction({...});

// Run additional compliance checks
const complianceResult = await runComplianceChecks(transaction.id);

if (complianceResult.passed) {
  // Move to processing
  await changeStatus(transaction.id, 'PROCESSING');

  // Complete transaction
  await changeStatus(transaction.id, 'SUCCESSFUL');
} else {
  // Decline due to compliance issues
  await changeStatus(transaction.id, 'DECLINED');
}
```

### 3. Fraud Detection Response

```javascript theme={null}
// Monitor transaction updates
if (fraudDetected) {
  // Immediately suspend transaction
  await changeStatus(transactionId, 'SUSPENDED');

  // Create alert for investigation
  await createAlert({
    transactionId,
    type: 'fraud_suspected',
    severity: 'high'
  });

  // After investigation, take action
  if (confirmed) {
    await changeStatus(transactionId, 'DECLINED');
  } else {
    await changeStatus(transactionId, 'SUCCESSFUL');
  }
}
```

### 4. Bulk Status Updates

```javascript theme={null}
// Update multiple transactions in parallel
const suspendedTransactions = await getTransactionsByStatus('SUSPENDED');

const results = await Promise.allSettled(
  suspendedTransactions.map(async (txn) => {
    if (shouldApprove(txn)) {
      return await changeStatus(txn.id, 'SUCCESSFUL');
    } else if (shouldDecline(txn)) {
      return await changeStatus(txn.id, 'DECLINED');
    }
  })
);

console.log(`Updated ${results.filter(r => r.status === 'fulfilled').length} transactions`);
```

## Best Practices

1. **Validate before changing** - Always check the current status before attempting a status change to avoid unnecessary API calls

2. **Handle transition errors** - Implement proper error handling for invalid transitions, as closed transactions cannot be reopened

3. **Use appropriate statuses** - Choose the correct status that reflects the actual business state of the transaction

4. **Monitor rule execution** - Pay attention to `rulesExecutionSummary` to ensure update rules are triggering as expected and check execution details, warnings, and metadata

5. **Implement audit logging** - Track all status changes in your system for compliance and debugging purposes

6. **Bulk updates** - When updating multiple transactions, use Promise.allSettled() to continue processing even if some updates fail

7. **Webhook integration** - Consider setting up webhooks to receive notifications when status changes trigger important rules

8. **Testing state transitions** - Test all possible state transitions in your development environment before deploying to production

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Create Transaction" icon="plus" href="/en/use-cases/transaction-monitoring/api-reference">
    Create new transactions
  </Card>

  <Card title="Get Transaction" icon="eye" href="/en/api-reference/transactions/get">
    Retrieve transaction details
  </Card>

  <Card title="Rules Configuration" icon="sliders" href="/en/use-cases/transaction-monitoring/rules-configuration">
    Configure update rules
  </Card>

  <Card title="Overview" icon="book" href="/en/use-cases/transaction-monitoring/overview">
    Back to overview
  </Card>
</CardGroup>
