> ## 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.

# Create Organization (Staff)

> Create an organization exactly as ChainPatrol staff do from the app: the owner and the calling staff user are added as members, default asset groups and any initial brands are created, and the website and official assets are allowlisted. Only ChainPatrol staff can call this endpoint, with a staff session or a staff user API key; organization API keys and customer accounts receive 403. The website and official assets are allowlisted automatically, except any that are currently BLOCKED: those are skipped and listed in `skippedAssets`.

> [!WARNING]
>
> This endpoint is only available to ChainPatrol staff. Customer API keys and
> customer accounts receive `403 Forbidden`.

## Overview

Create a new customer organization exactly as ChainPatrol staff do from
**Staff → Organizations → Create** in the app. In one call it:

* creates the organization with the services you enable
* adds the owner (reusing an existing user with that email) as `OWNER`, and
  the calling staff user as `ADMIN`
* creates the default asset groups and any initial brands
* creates the website as a monitored asset and allowlists it, together with
  any official assets you list

## Authentication

Authenticate with a **staff user API key** in the `X-API-KEY` header, or a
staff session token as `Authorization: Bearer <token>`. Organization API keys,
customer users, and read-only staff service accounts are refused.

### Example Request

```bash cURL theme={null}
curl -X POST 'https://app.chainpatrol.io/api/v2/staff/organization/create' \
  -H 'X-API-KEY: YOUR_STAFF_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "organization": {
      "name": "Acme",
      "slug": "acme",
      "websiteUrl": "https://acme.com",
      "twitterHandle": "@acme",
      "subscriptionStatus": "PROSPECT",
      "accountExecName": "Jane Doe",
      "accountExecEmail": "jane@chainpatrol.io",
      "isReportingActive": true,
      "isReviewingActive": true,
      "isDetectionActive": true,
      "requiresCustomerReview": true
    },
    "owner": {
      "fullName": "John Smith",
      "email": "john@acme.com"
    },
    "brands": [
      {
        "name": "Acme",
        "slug": "acme",
        "type": "ORGANIZATION",
        "includedTerms": "*acme*",
        "officialAssets": ["https://twitter.com/acme"]
      }
    ]
  }'
```

```typescript TypeScript theme={null}
const response = await fetch(
  "https://app.chainpatrol.io/api/v2/staff/organization/create",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-KEY": "YOUR_STAFF_API_KEY",
    },
    body: JSON.stringify({
      organization: {
        name: "Acme",
        slug: "acme",
        websiteUrl: "https://acme.com",
        accountExecName: "Jane Doe",
        accountExecEmail: "jane@chainpatrol.io",
      },
      owner: { fullName: "John Smith", email: "john@acme.com" },
    }),
  }
);

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

## Response

```json theme={null}
{
  "organization": {
    "id": 1234,
    "name": "Acme",
    "slug": "acme",
    "description": null,
    "websiteUrl": "https://acme.com",
    "subscriptionStatus": "PROSPECT",
    "createdAt": "2026-10-15T12:00:00.000Z"
  },
  "owner": {
    "id": 5678,
    "email": "john@acme.com",
    "fullName": "John Smith"
  },
  "brands": [{ "id": 91, "name": "Acme" }],
  "brandAssetErrors": [],
  "skippedAssets": [],
  "dashboardUrl": "https://app.chainpatrol.io/admin/acme/dashboard"
}
```

`skippedAssets` lists assets that were not added or allowlisted because they
are currently blocked, for example a known scam domain passed as an official
asset. Review them before allowlisting anything by hand.

`brandAssetErrors` lists brands whose official assets could not be added. The
organization and its brands are still created; add those assets again from the
app or the [Add Organization Assets](https://chainpatrol.com/docs/external-api/organization-assets-add.md)
endpoint.

## Errors

| Status | When |
| - | - |
| `400` | Validation failed, e.g. an invalid Twitter handle, unsupported asset, or brand term conflict. The message names the field. |
| `401` | No API key or session was provided. |
| `403` | The caller is not ChainPatrol staff, or the credential is read-only. |
| `409` | The organization slug or a brand slug is taken, or the website already belongs to another organization. |

## Notes

* The request is validated with the same rules as the app's create form, so
  anything the app refuses is refused here too.
* Omitted settings take the app form's defaults: reporting, reviewing and
  detection on, customer review off, and subscription status `PROSPECT`.
  Other services stay off unless you enable them.
* Enabling an automated service (for example `isAutomatedReviewingActive`)
  requires its manual counterpart (`isReviewingActive`).
* Official assets already owned by another organization are skipped rather
  than reassigned.
* Assets that are currently **blocked** are never added to the organization or
  allowlisted, whether they come in as the website, `officialAssets` or a
  brand's `officialAssets`. They are listed in `skippedAssets` instead, and the
  organization is still created.


## OpenAPI

````yaml POST /staff/organization/create
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:
  /staff/organization/create:
    post:
      tags:
        - organization
        - staff
      summary: Create an organization (staff only)
      description: >-
        Create an organization exactly as ChainPatrol staff do from the app: the
        owner and the calling staff user are added as members, default asset
        groups and any initial brands are created, and the website and official
        assets are allowlisted. Only ChainPatrol staff can call this endpoint,
        with a staff session or a staff user API key; organization API keys and
        customer accounts receive 403. The website and official assets are
        allowlisted automatically, except any that are currently BLOCKED: those
        are skipped and listed in `skippedAssets`.
      operationId: staffOrganizationCreate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                organization:
                  type: object
                  properties:
                    name:
                      type: string
                      minLength: 1
                      maxLength: 255
                      description: Organization name
                    slug:
                      type: string
                      minLength: 1
                      description: >-
                        Unique organization slug: lowercase letters, numbers and
                        dashes. Used in dashboard URLs and API calls
                    description:
                      type: string
                      description: Short description
                    websiteUrl:
                      type: string
                      format: uri
                      description: >-
                        Primary website. Created as a monitored asset of the
                        organization and allowlisted. Refused when another
                        organization already owns it, and skipped (see
                        `skippedAssets`) when it is currently BLOCKED
                    industry:
                      type: string
                      enum:
                        - crypto_web3
                        - banking
                        - financial_services
                        - fintech
                        - insurance
                        - payments
                        - investment_asset_management
                        - accounting
                        - technology_software
                        - saas
                        - cybersecurity
                        - cloud_infrastructure
                        - hardware_semiconductors
                        - consumer_electronics
                        - artificial_intelligence
                        - telecommunications
                        - social_media
                        - ecommerce
                        - retail
                        - consumer_goods
                        - food_and_beverage
                        - fashion_apparel
                        - luxury_goods
                        - beauty_cosmetics
                        - healthcare
                        - pharmaceuticals
                        - biotechnology
                        - medical_devices
                        - media_entertainment
                        - gaming_esports
                        - sports
                        - travel_hospitality
                        - airlines_aviation
                        - automotive
                        - transportation_logistics
                        - energy_utilities
                        - oil_and_gas
                        - mining_metals
                        - chemicals
                        - manufacturing_industrial
                        - aerospace_defense
                        - construction
                        - real_estate
                        - agriculture
                        - education
                        - government_public_sector
                        - nonprofit_ngo
                        - legal_services
                        - professional_services
                        - marketing_advertising
                        - human_resources
                        - fitness_wellness
                        - other
                      description: Industry
                    twitterHandle:
                      type: string
                      description: Twitter / X handle, including the leading "@"
                    avatarUrl:
                      type: string
                      format: uri
                      description: Logo URL
                    subscriptionStatus:
                      type: string
                      enum:
                        - POC
                        - ACTIVE
                        - PROSPECT
                        - INTEGRATION
                        - INACTIVE
                        - PROTECTION
                      default: PROSPECT
                      description: >-
                        Subscription status. Defaults to `PROSPECT`, as in the
                        app
                    accountExecName:
                      type: string
                      minLength: 1
                      description: >-
                        Name of the ChainPatrol account executive for this
                        customer
                    accountExecEmail:
                      type: string
                      format: email
                      description: >-
                        Email of the ChainPatrol account executive for this
                        customer
                    isReportingActive:
                      type: boolean
                      default: true
                      description: Enable reporting. Defaults to `true`, as in the app
                    isAutomatedReportingActive:
                      type: boolean
                      description: Enable automated reporting. Requires reporting
                    isReviewingActive:
                      type: boolean
                      default: true
                      description: Enable reviewing. Defaults to `true`, as in the app
                    isAutomatedReviewingActive:
                      type: boolean
                      description: Enable automated reviewing. Requires reviewing
                    isProtectionActive:
                      type: boolean
                      description: Enable protection (blocklisting)
                    isAutomatedProtectionActive:
                      type: boolean
                      description: Enable automated protection. Requires protection
                    isTakedownsActive:
                      type: boolean
                      description: Enable takedowns
                    isDetectionActive:
                      type: boolean
                      default: true
                      description: Enable detection. Defaults to `true`, as in the app
                    requiresCustomerReview:
                      type: boolean
                      default: false
                      description: >-
                        Require the customer to approve proposals before they
                        take effect. Defaults to `false`, as in the app
                  required:
                    - name
                    - slug
                    - accountExecName
                    - accountExecEmail
                  description: The organization to create
                owner:
                  type: object
                  properties:
                    fullName:
                      type: string
                      minLength: 1
                      description: Owner's full name
                    email:
                      type: string
                      format: email
                      description: >-
                        Owner's email. An existing user with this email is
                        reused
                    avatarUrl:
                      type: string
                      format: uri
                      description: Owner's avatar URL
                  required:
                    - fullName
                    - email
                  description: The customer user who owns the organization
                officialAssets:
                  type: array
                  items:
                    type: object
                    properties:
                      content:
                        type: string
                        minLength: 1
                        description: Asset URL, handle or address
                      name:
                        type: string
                        description: Display name for the asset
                    required:
                      - content
                  description: >-
                    Official assets of the organization not tied to a brand.
                    Each is created (or claimed when unowned) and allowlisted.
                    Assets owned by another organization are skipped, and
                    currently BLOCKED assets are skipped and reported in
                    `skippedAssets`
                brands:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                        minLength: 1
                        maxLength: 255
                        description: Brand name
                      slug:
                        type: string
                        minLength: 1
                        description: >-
                          Globally unique brand slug: lowercase letters, numbers
                          and hyphens, not ending in a hyphen
                      type:
                        type: string
                        enum:
                          - INDIVIDUAL
                          - ORGANIZATION
                          - PRODUCT
                        description: >-
                          `ORGANIZATION` for the company or a sub-brand,
                          `INDIVIDUAL` for a person, `PRODUCT` for a product
                      websiteUrl:
                        type: string
                        description: Brand website URL
                      twitterHandle:
                        type: string
                        description: Brand Twitter / X handle, including the leading "@"
                      includedTerms:
                        type: string
                        description: >-
                          Comma-separated terms detection should match for this
                          brand. Loose terms need at least 6 characters; wrap
                          shorter terms as `*term*` for exact matching
                      excludedTerms:
                        type: string
                        description: >-
                          Comma-separated terms detection should ignore for this
                          brand
                      noOfficialAssets:
                        type: array
                        items:
                          type: string
                          enum:
                            - URL
                            - PAGE
                            - ADDRESS
                            - DISCORD
                            - LINKEDIN
                            - TWITTER
                            - FACEBOOK
                            - YOUTUBE
                            - REDDIT
                            - TELEGRAM
                            - GOOGLE_APP_STORE
                            - APPLE_APP_STORE
                            - AMAZON_APP_STORE
                            - MICROSOFT_APP_STORE
                            - TIKTOK
                            - INSTAGRAM
                            - THREADS
                            - MEDIUM
                            - CHROME_WEB_STORE
                            - MOZILLA_ADDONS
                            - OPERA_ADDONS
                            - EMAIL
                            - PATREON
                            - OPENSEA
                            - FARCASTER
                            - IPFS
                            - GOOGLE_FORM
                            - WHATSAPP
                            - DISCORD_USER
                            - QUORA
                            - GITHUB
                            - TEACHABLE
                            - SUBSTACK
                            - DEBANK
                            - TAWK_TO
                            - JOTFORM
                            - PRIMAL
                            - BLUESKY
                            - SNAPCHAT
                            - DESO
                            - PINTEREST
                            - FLICKR
                            - GALXE
                            - VELOG
                            - NPM
                            - PYPI
                            - HEX
                            - DOCKER_HUB
                            - VOCAL_MEDIA
                            - TECKFINE
                            - TENDERLY
                            - HACKMD
                            - ETSY
                            - ZAZZLE
                            - BASENAME
                            - BILIBILI_TV
                            - VIMEO
                            - DAILYMOTION
                            - PHONE_NUMBER
                            - SLACK
                            - CALENDLY
                            - NGROK
                            - RARIBLE
                            - RUST_PACKAGE
                            - FLATHUB
                            - VIDLII
                            - VEVIOZ
                            - ISSUU
                            - SOUNDCLOUD
                            - ZAPPER
                            - REDNOTE
                            - SAMSUNG_APP_STORE
                            - HUAWEI_APP_STORE
                            - XIAOMI_APP_STORE
                            - TENCENT_APP_STORE
                            - OPPO_APP_STORE
                            - VIVO_APP_STORE
                            - F_DROID
                            - GOOGLE_AD
                            - BING_AD
                            - TWITCH
                            - BEHANCE
                            - ZORA
                            - META_AD
                            - SIGNAL
                            - DEVIANTART
                            - BANDCAMP
                            - ARCHIVE_ORG
                            - FIVE_HUNDRED_PX
                            - LUMA
                            - SMARTMONEYMATCH
                            - APK_GOLD
                            - GLASSDOOR
                            - PUMP_FUN
                            - TUMBLR
                            - MASTODON
                        description: >-
                          Asset types this brand has no official account on, so
                          lookalikes on those platforms are not expected to be
                          official
                      officialAssets:
                        type: array
                        items:
                          type: string
                        description: >-
                          Official assets (URLs, social profiles, addresses) to
                          attach to this brand and allowlist
                    required:
                      - name
                      - slug
                      - type
                  minItems: 1
                  description: Initial brands. When provided, at least one is required
              required:
                - organization
                - owner
              description: >-
                Create an organization (staff only)


                Creates an organization exactly as ChainPatrol staff do from the
                app: the owner

                and the calling staff user are added as members, default asset
                groups and any

                initial brands are created, and the website and official assets
                are allowlisted.


                Only ChainPatrol staff can call this endpoint, with a staff
                session or a staff

                user API key. Organization API keys and customer accounts
                receive 403.
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  organization:
                    type: object
                    properties:
                      id:
                        type: number
                        description: Organization ID
                      name:
                        type: string
                        description: Organization name
                      slug:
                        type: string
                        description: Organization slug
                      description:
                        type: string
                        nullable: true
                        description: Description
                      websiteUrl:
                        type: string
                        nullable: true
                        description: Website URL
                      subscriptionStatus:
                        type: string
                        enum:
                          - POC
                          - ACTIVE
                          - PROSPECT
                          - INTEGRATION
                          - INACTIVE
                          - PROTECTION
                        description: Subscription status
                      createdAt:
                        type: string
                        description: When the organization was created
                    required:
                      - id
                      - name
                      - slug
                      - description
                      - websiteUrl
                      - subscriptionStatus
                      - createdAt
                  owner:
                    type: object
                    properties:
                      id:
                        type: number
                        description: User ID of the owner
                      email:
                        type: string
                        description: Owner's email
                      fullName:
                        type: string
                        nullable: true
                        description: Owner's full name
                    required:
                      - id
                      - email
                      - fullName
                  brands:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: number
                          description: Brand ID
                        name:
                          type: string
                          description: Brand name
                      required:
                        - id
                        - name
                    description: Brands created with the organization
                  brandAssetErrors:
                    type: array
                    items:
                      type: object
                      properties:
                        brandName:
                          type: string
                          description: Brand whose official assets failed
                        message:
                          type: string
                          description: Why they could not be added
                      required:
                        - brandName
                        - message
                    description: >-
                      Brands whose official assets could not be added. The
                      organization and brands were still created; add the assets
                      again from the app or API
                  skippedAssets:
                    type: array
                    items:
                      type: object
                      properties:
                        content:
                          type: string
                          description: The asset that was skipped
                        brandName:
                          type: string
                          nullable: true
                          description: >-
                            Brand it was listed under, or null for the website
                            and `officialAssets`
                        reason:
                          type: string
                          description: Why it was skipped
                      required:
                        - content
                        - brandName
                        - reason
                    description: >-
                      Website and official assets that were not added or
                      allowlisted because they are currently BLOCKED. The
                      organization was still created; review these assets before
                      allowlisting them
                  dashboardUrl:
                    type: string
                    description: Link to the organization's dashboard
                required:
                  - organization
                  - owner
                  - brands
                  - brandAssetErrors
                  - skippedAssets
                  - dashboardUrl
                description: Successful operation
        '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.