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

# Set Organization Asset Expiry

> Set, renew or clear when assets drop off your organization's allowlist. After the expiry passes, assets stay for a 14-day grace period, then are removed from your organization; their status does not change. Requires an organization API key with write access, or an organization owner or admin.

## Overview

Set, renew or clear when assets drop off your organization's allowlist. Use it for assets that should only stay for a while, such as a partner's website.

When an asset's expiry passes, it stays allowed and on your organization for a **14-day grace period**, then it is removed from your organization and monitoring for it stops. Its status does not change. Organization owners and admins get a daily email digest about upcoming expiries and removals. See [Expiry](/docs/concepts/allowlist#expiry) for the full timeline.

* Setting a date on an expired asset renews it and ends its grace period.
* Passing `null` clears the expiry, so the assets stay indefinitely.
* The request is all or nothing: if any asset is not on your organization, nothing changes.

## Quick Start

### Authentication

Include your API key in the `X-API-KEY` header:

```bash theme={null}
X-API-KEY: your_api_key_here
```

An organization API key needs read and write access. With user credentials, pass `slug`; you must be an owner or admin of that organization.

### Example Request

```typescript TypeScript theme={null}
const response = await fetch(
  "https://app.chainpatrol.io/api/v2/organization/assets/expiry",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-KEY": "YOUR_API_KEY_HERE",
    },
    body: JSON.stringify({
      assetIds: [12345, 12346],
      expiresAt: "2027-04-30T23:59:59Z",
    }),
  }
);

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

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

response = requests.post(
    "https://app.chainpatrol.io/api/v2/organization/assets/expiry",
    headers={
        "Content-Type": "application/json",
        "X-API-KEY": "YOUR_API_KEY_HERE",
    },
    json={
        "assetIds": [12345, 12346],
        "expiresAt": "2027-04-30T23:59:59Z",
    },
)

print(response.json())
```

```bash cURL theme={null}
curl -X POST 'https://app.chainpatrol.io/api/v2/organization/assets/expiry' \
  -H 'X-API-KEY: YOUR_API_KEY_HERE' \
  -H 'Content-Type: application/json' \
  -d '{
    "assetIds": [12345, 12346],
    "expiresAt": "2027-04-30T23:59:59Z"
  }'
```

To clear the expiry, send `"expiresAt": null`.

## Request Body

| Field | Type | Required | Description |
| - | - | - | - |
| assetIds | number\[] | Yes | IDs of your organization's assets, 1 to 5000 per request. Get them from [List Organization Assets](/docs/external-api/organization-assets-list). |
| expiresAt | string \| null | Yes | When the assets expire, as an ISO 8601 date-time in the future. `null` clears the expiry. |
| slug | string | No | Organization slug. Optional for organization API keys; required when your credentials can reach more than one organization. |

## Response

### Success Response

```json theme={null}
{
  "updatedCount": 2,
  "expiresAt": "2027-04-30T23:59:59.000Z"
}
```

### Response Fields

| Field | Type | Description |
| - | - | - |
| updatedCount | number | Number of assets updated |
| expiresAt | string \| null | The expiry that was set, or `null` when it was cleared |

The [List Organization Assets](/docs/external-api/organization-assets-list) response shows each asset's `allowlistExpiresAt`, and `allowlistExpiredAt` once its grace period has started.

## Error Responses

### 400 Bad Request

Returned when `expiresAt` is not in the future, or the body is malformed:

```json theme={null}
{
  "error": {
    "code": "BAD_REQUEST",
    "message": "`expiresAt` must be in the future"
  }
}
```

### 401 Unauthorized

Returned when no `slug` is passed and the credentials are not scoped to an organization:

```json theme={null}
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Pass `slug` to choose an organization, or authenticate with an API key scoped to one"
  }
}
```

### 403 Forbidden

Returned when the API key is read-only, belongs to a different organization than `slug`, or the user is not an owner or admin of the organization.

### 404 Not Found

Returned when any of the assets is not on your organization. Nothing is changed:

```json theme={null}
{
  "error": {
    "code": "NOT_FOUND",
    "message": "Assets not found on this organization: 12346"
  }
}
```

## Use Cases

### Expire partner assets after a year

```typescript theme={null}
const oneYearFromNow = new Date();
oneYearFromNow.setUTCFullYear(oneYearFromNow.getUTCFullYear() + 1);
oneYearFromNow.setUTCHours(23, 59, 59, 999);

await fetch("https://app.chainpatrol.io/api/v2/organization/assets/expiry", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-API-KEY": "YOUR_API_KEY_HERE",
  },
  body: JSON.stringify({
    assetIds: partnerAssetIds,
    expiresAt: oneYearFromNow.toISOString(),
  }),
});
```

### From the CLI or MCP

```bash theme={null}
chainpatrol orgs assets set-expiry 12345 12346 --in 1y
```

The [MCP server](/docs/mcp-server) exposes the same operation as the `organization_assets_set_expiry` tool.


## OpenAPI

````yaml POST /organization/assets/expiry
openapi: 3.0.3
info:
  title: ChainPatrol External API - OpenAPI 3.0
  description: ChainPatrol External API documentation
  version: 2.0.0
servers:
  - url: https://app.chainpatrol.io/api/v2
security: []
tags:
  - name: asset
  - name: report
  - name: dark-web
externalDocs:
  url: https://chainpatrol.com/docs
paths:
  /organization/assets/expiry:
    post:
      tags:
        - organization
      summary: Set organization asset expiry
      description: >-
        Set, renew or clear when assets drop off your organization's allowlist.
        After the expiry passes, assets stay for a 14-day grace period, then are
        removed from your organization; their status does not change. Requires
        an organization API key with write access, or an organization owner or
        admin.
      operationId: organizationAssetsSetExpiry
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                slug:
                  type: string
                  description: >-
                    Organization slug. Optional for organization-scoped API
                    keys, which resolve the organization from the key itself.
                    Required when your credentials can reach more than one
                    organization.
                assetIds:
                  type: array
                  items:
                    type: integer
                    minimum: 0
                    exclusiveMinimum: true
                  minItems: 1
                  maxItems: 5000
                  description: >-
                    IDs of the organization's assets to update (max 5000 per
                    request)
                expiresAt:
                  type: string
                  nullable: true
                  format: date-time
                  description: >-
                    When the assets expire, as an ISO 8601 date-time in the
                    future (e.g. `2027-04-30T23:59:59Z`). `null` clears the
                    expiry so the assets stay indefinitely.
              required:
                - assetIds
                - expiresAt
              description: >-
                Set when organization assets expire


                Sets, renews or clears the allowlist expiry of assets on your
                organization. Use it

                for assets that should only stay for a while, such as a
                partner's site. When the

                date passes, the assets stay on your organization for a 14-day
                grace period, then

                are removed from it. Their status does not change. Setting a new
                date on an

                expired asset renews it and ends its grace period.
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  updatedCount:
                    type: number
                    description: Number of assets updated
                  expiresAt:
                    type: string
                    nullable: true
                    description: The expiry that was set, or `null` when it was cleared
                required:
                  - updatedCount
                  - expiresAt
                description: Expiry update result
        '400':
          description: Invalid input data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.BAD_REQUEST'
        '401':
          description: Authorization not provided
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.UNAUTHORIZED'
        '403':
          description: Insufficient access
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.FORBIDDEN'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error.INTERNAL_SERVER_ERROR'
      security:
        - ApiKey: []
components:
  schemas:
    error.BAD_REQUEST:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Invalid input data
        code:
          type: string
          description: The error code
          example: BAD_REQUEST
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Invalid input data error (400)
      description: The error information
      example:
        code: BAD_REQUEST
        message: Invalid input data
        issues: []
    error.UNAUTHORIZED:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Authorization not provided
        code:
          type: string
          description: The error code
          example: UNAUTHORIZED
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Authorization not provided error (401)
      description: The error information
      example:
        code: UNAUTHORIZED
        message: Authorization not provided
        issues: []
    error.FORBIDDEN:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Insufficient access
        code:
          type: string
          description: The error code
          example: FORBIDDEN
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Insufficient access error (403)
      description: The error information
      example:
        code: FORBIDDEN
        message: Insufficient access
        issues: []
    error.INTERNAL_SERVER_ERROR:
      type: object
      properties:
        message:
          type: string
          description: The error message
          example: Internal server error
        code:
          type: string
          description: The error code
          example: INTERNAL_SERVER_ERROR
        issues:
          type: array
          items:
            type: object
            properties:
              message:
                type: string
            required:
              - message
          description: An array of issues that were responsible for the error
          example: []
      required:
        - message
        - code
      title: Internal server error error (500)
      description: The error information
      example:
        code: INTERNAL_SERVER_ERROR
        message: Internal server error
        issues: []
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-KEY
      description: >-
        Your API key. This is required by most endpoints to access our API
        programatically. Reach out to us at
        [support@chainpatrol.io](mailto:support@chainpatrol.io?subject=Re:%20API%20Key%20for%20SDK&body=Company:%20%0AName:%20%0APurpose:%20)
        to get an API key for your use.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.