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

# API Call Field

> External API data fetch for credit checks, verification, and lookups

The API Call field fetches data from external APIs and stores the response in the case. This field type enables real-time data enrichment from third-party services — credit scores, company data verification, address lookups, exchange rates, and any external data source with an API.

Use API Call fields when you need to pull data from external systems dynamically during case workflows, rather than asking users to manually provide information that exists in other systems.

## When to Use

**Use API Call fields for:**

* Credit score checks
* Company data verification (registration, VAT validation)
* Address validation and geocoding
* Bank account verification (IBAN validation)
* Identity verification
* Exchange rate lookups
* Tax ID validation
* Property data lookups
* Vehicle registration lookups
* API-based enrichment services

**Consider alternatives:**

* Use **Text**, **Number**, or other fields for manual data entry
* Use integrations for bidirectional sync with external systems
* Use webhooks for pushing data to external systems

## Configuration Options

| Option           | Description                   | Type   | Default          | Example                      |
| ---------------- | ----------------------------- | ------ | ---------------- | ---------------------------- |
| `key`            | Unique identifier             | String | Required         | `credit_score`               |
| `name`           | Display label                 | String | Required         | "Credit Score"               |
| `description`    | Help text for users           | String | Optional         | "Fetched from credit bureau" |
| `api_config`     | API configuration object      | Object | Required         | See below                    |
| `trigger`        | When to execute API call      | String | `on_create`      | `on_update`, `manual`        |
| `retry`          | Number of retry attempts      | Number | `3`              | `5`                          |
| `timeout`        | Request timeout (ms)          | Number | `30000`          | `10000`                      |
| `cache_duration` | Cache response (seconds)      | Number | `0`              | `3600`                       |
| `visibility`     | Display setting               | String | `always-visible` | `hide-when-empty`            |
| `section`        | Section this field belongs to | String | None             | Section UUID                 |

### API Configuration Object

| Property           | Description                      | Type   | Required | Example                                 |
| ------------------ | -------------------------------- | ------ | -------- | --------------------------------------- |
| `url`              | API endpoint URL                 | String | Yes      | `https://api.example.com/credit`        |
| `method`           | HTTP method                      | String | Yes      | `GET`, `POST`                           |
| `headers`          | Request headers                  | Object | No       | `{"Authorization": "Bearer {token}"}`   |
| `params`           | Query parameters                 | Object | No       | `{"vat": "{data.vat_number}"}`          |
| `body`             | Request body (for POST/PUT)      | Object | No       | `{"customer_id": "{data.customer_id}"}` |
| `auth`             | Authentication config            | Object | No       | See below                               |
| `response_mapping` | How to map response to case data | Object | Yes      | See below                               |

### Authentication

| Type           | Configuration                                                            | Example           |
| -------------- | ------------------------------------------------------------------------ | ----------------- |
| Bearer Token   | `{"type": "bearer", "token": "{secret.api_token}"}`                      | API key auth      |
| Basic Auth     | `{"type": "basic", "username": "user", "password": "{secret.password}"}` | Username/password |
| API Key Header | `{"type": "header", "key": "X-API-Key", "value": "{secret.api_key}"}`    | Custom header     |

## Examples

### Credit Score Lookup

Fetch credit score from external bureau:

```json theme={null}
{
  "key": "credit_score",
  "type": "api_call",
  "name": "Credit Score",
  "description": "Credit score fetched from bureau",
  "trigger": "manual",
  "api_config": {
    "url": "https://api.creditbureau.com/v1/score",
    "method": "POST",
    "auth": {
      "type": "bearer",
      "token": "{secret.credit_bureau_token}"
    },
    "body": {
      "ssn": "{data.ssn}",
      "dob": "{data.birth_date}"
    },
    "response_mapping": {
      "score": "score",
      "rating": "rating",
      "last_updated": "timestamp"
    }
  }
}
```

### VAT Number Validation

Validate European VAT number:

```json theme={null}
{
  "key": "vat_validation",
  "type": "api_call",
  "name": "VAT Validation",
  "description": "Validates company VAT number",
  "trigger": "on_update",
  "api_config": {
    "url": "https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number",
    "method": "GET",
    "params": {
      "vatNumber": "{data.vat_number}",
      "countryCode": "{data.country}"
    },
    "response_mapping": {
      "valid": "valid",
      "company_name": "traderName",
      "address": "traderAddress"
    }
  }
}
```

### Company Data Enrichment

Fetch company details from registry:

```json theme={null}
{
  "key": "company_data",
  "type": "api_call",
  "name": "Company Data",
  "description": "Company information from business register",
  "trigger": "on_create",
  "cache_duration": 86400,
  "api_config": {
    "url": "https://api.companyreg.com/v2/companies/{data.company_id}",
    "method": "GET",
    "headers": {
      "Authorization": "Bearer {secret.company_api_token}"
    },
    "response_mapping": {
      "legal_name": "name",
      "registration_date": "incorporationDate",
      "status": "status",
      "employees": "numberOfEmployees",
      "revenue": "annualRevenue"
    }
  }
}
```

### Address Geocoding

Convert address to coordinates:

```json theme={null}
{
  "key": "geocode",
  "type": "api_call",
  "name": "Geocode Address",
  "description": "Latitude and longitude of address",
  "trigger": "on_update",
  "api_config": {
    "url": "https://maps.googleapis.com/maps/api/geocode/json",
    "method": "GET",
    "params": {
      "address": "{data.full_address}",
      "key": "{secret.google_maps_key}"
    },
    "response_mapping": {
      "latitude": "results[0].geometry.location.lat",
      "longitude": "results[0].geometry.location.lng",
      "formatted_address": "results[0].formatted_address"
    }
  }
}
```

## Trigger Types

Control when the API call executes:

| Trigger     | When It Runs                   | Use Case                |
| ----------- | ------------------------------ | ----------------------- |
| `on_create` | When case is created           | Initial data enrichment |
| `on_update` | When specified fields change   | Validate updated data   |
| `manual`    | When user/member clicks button | User-initiated checks   |
| `scheduled` | On specified schedule          | Regular updates         |

**Watch fields for on\_update:**

```json theme={null}
{
  "trigger": "on_update",
  "watch_fields": ["data.vat_number", "data.country"]
}
```

The API call executes only when watched fields change.

## Response Mapping

Map API response to case data fields:

**Simple mapping:**

```json theme={null}
{
  "response_mapping": {
    "score": "credit_score",
    "rating": "credit_rating"
  }
}
```

**Nested response:**

```json theme={null}
{
  "response_mapping": {
    "company_name": "data.company.name",
    "employees": "data.company.employeeCount",
    "address": "data.company.address.full"
  }
}
```

**Array access:**

```json theme={null}
{
  "response_mapping": {
    "first_result": "results[0].value"
  }
}
```

**Transform with penscript:**

```json theme={null}
{
  "response_mapping": {
    "score_normalized": {":div": "{response.score}", "10"}
  }
}
```

## Error Handling

API Call fields handle errors gracefully:

### Retry Logic

* Automatically retries on timeout or 5xx errors
* Configurable retry count with exponential backoff
* Failed requests don't block case workflow

### Timeout

* Default: 30 seconds
* Configurable with `timeout` option
* Prevents hanging on slow APIs

### Error Storage

* Error messages stored in field metadata
* Visible to case managers
* Can trigger automations or alerts

**Example error response:**

```json theme={null}
{
  "error": true,
  "message": "API timeout after 30s",
  "timestamp": "2026-02-10T14:30:00Z"
}
```

## Caching

Cache API responses to reduce calls:

**No caching (default):**

```json theme={null}
{"cache_duration": 0}
```

**Cache for 1 hour:**

```json theme={null}
{"cache_duration": 3600}
```

**Cache for 24 hours:**

```json theme={null}
{"cache_duration": 86400}
```

**Use caching for:**

* Static data (company info, address validation)
* Rate-limited APIs
* Expensive API calls

**Don't cache:**

* Real-time data (exchange rates, stock prices)
* Frequently changing data
* Time-sensitive information

## Security Considerations

### Store Secrets Securely

* Never hardcode API keys in configuration
* Use `{secret.key_name}` syntax for credentials
* Store secrets in workspace secrets management
* Rotate secrets regularly

### Validate Responses

* Validate API response structure
* Handle missing or malformed data
* Set appropriate timeouts
* Implement retry limits

### Rate Limiting

* Respect API provider rate limits
* Use caching to reduce calls
* Implement backoff strategies
* Monitor API usage

### Data Privacy

* Only fetch necessary data
* Be aware of GDPR implications when fetching personal data
* Document what external APIs you use
* Review third-party data processing agreements

## Best Practices

**Use for enrichment, not critical data:**

* Don't rely solely on API calls for essential data
* Provide fallback for API failures
* Allow manual override when API unavailable

**Configure appropriate triggers:**

* `on_create` for initial enrichment
* `on_update` for validation after user input
* `manual` for expensive or optional checks
* Don't trigger unnecessarily (costs, rate limits)

**Map responses completely:**

* Extract all useful data from response
* Store metadata (timestamps, validation status)
* Handle nested and array responses
* Transform data as needed

**Handle errors gracefully:**

* Show user-friendly error messages
* Log technical details for debugging
* Don't block workflow on API failure
* Provide manual data entry alternative

**Cache appropriately:**

* Cache stable data (company info, validation results)
* Don't cache changing data (prices, availability)
* Set reasonable cache durations
* Clear cache when underlying data changes

**Monitor API usage:**

* Track call volume and success rate
* Monitor response times
* Watch for rate limit warnings
* Budget for API costs

**Document external dependencies:**

* List all APIs used
* Document authentication requirements
* Note rate limits and costs
* Maintain fallback procedures

***

## Related Field Types

<CardGroup cols={2}>
  <Card title="Text" icon="text" href="/cases/data_schema/text">
    Use for manual data entry
  </Card>

  <Card title="Number" icon="hashtag" href="/cases/data_schema/number">
    Store numeric API responses
  </Card>

  <Card title="Automations" icon="bolt" href="/cases/automations">
    Trigger workflows based on API responses
  </Card>

  <Card title="Data Schema Overview" icon="sitemap" href="/cases/data_schema">
    Back to Data Schema overview
  </Card>
</CardGroup>
