/resellers/{id}/promote - Promote reseller to distributor

Add MCP server to your AI tool

Allow AI tools and LLMs to interact with the API documentation portal through MCP.

MCP server URL

https://api.my.nethesis.it/mcp

Standard setup for AI tools providing an mcp.json file

mcp.json
{
  "my.nethesis.it MCP server": {
    "url": "https://api.my.nethesis.it/mcp"
  }
}

Close
PATCH /resellers/{id}/promote

Move a reseller one level up to distributor, in place. Restricted to owner-level authority: a user of the Owner organization, or a Super Admin. A Super Admin that does not belong to the Owner organization acts within its own scope only — it can promote the resellers its own organization manages, never a peer's and never the organization it belongs to (403 otherwise).

The organization keeps its id and logto_id, so its customers, users, systems, applications, alert history and Mimir tenant stay attached. Its custom_data.createdBy moves to the Owner organization, so the distributor that manages it drops it — and the customers under it — from its scope, and the alerting config chain stops inheriting that distributor's layer.

Members get the Distributor organization role in place of Reseller, so each of them picks up the new level at the next login or token refresh.

Rejected with 409 when the reseller is suspended (reactivate it first), when it is not yet synced with Logto, or when the Owner organization cannot be resolved; with 400 when its VAT already belongs to an active distributor (VAT is unique per level). Both carry the validation_error shape with stable message codes — see the individual responses.

Path parameters

  • id string Required

    Reseller Logto ID

Responses

  • 200 application/json

    Reseller promoted successfully

    Hide response attributes Show response attributes object
    • code integer
    • message string
    • data object
      Hide data attributes Show data attributes object
      • distributor object
        Hide distributor attributes Show distributor attributes object
        • id string

          Database UUID of the organization

        • logto_id string

          Logto organization ID (use this value for assignment operations)

        • name string

          Organization name

        • description string

          Organization description

        • custom_data object

          Custom organization data

          Additional properties are allowed.

        • suspended_at string(date-time) | null

          Timestamp when the organization was suspended. NULL means enabled, non-NULL means blocked/suspended.

        • suspended_by_org_id string | null

          Organization ID that caused cascade suspension (for resellers and customers only). NULL means directly suspended or not suspended. When set, the entity can only be reactivated by the parent organization that initiated the cascade.

        • rebranding_enabled boolean

          Whether rebranding is active for this organization (directly or inherited from parent)

        • rebranding_org_id string | null

          The organization ID that provides the rebranding (the org where rebranding is configured). Only present when rebranding_enabled is true.

        • created_by object

          Snapshot of the user who created an organization (distributor, reseller or customer). The user identity fields are point-in-time; organization_name is kept in sync when the referenced organization is renamed.

          Hide created_by attributes Show created_by attributes object
          • user_id string

            Logto ID of the user who created the organization

          • username string

            Username of the creator

          • name string

            Full name of the creator

          • email string

            Email of the creator

          • organization_id string

            Organization ID the creator belongs to

          • organization_name string

            Organization name the creator belongs to

          • on_behalf_of boolean

            True when the organization was attributed to a different organization via created_by_organization_id (the user acted on behalf of organization_name rather than belonging to it). Omitted when false.

      • detached_from_organization_id string

        Distributor that drops the promoted organization and its customers from its scope

      • parent_organization_id string

        Owner organization recorded as the promoted organization's createdBy

      • customers_count integer

        Customers still attached to the promoted organization

      • users_count integer

        Users still attached to the promoted organization

      • systems_count integer

        Systems still owned by the promoted organization

      • members_role_switched integer

        Members whose Logto organization role moved from Reseller to Distributor

      • warnings array[string]

        Best-effort steps that did not confirm and need an operator check

  • 400 application/json

    Validation failed. data.type is always validation_error and data.errors[] carries a stable message code the UI turns into an i18n key: already exists on custom_data.vat when the VAT already belongs to an active distributor (value is the VAT).

    Hide response attributes Show response attributes object
    • code integer

      HTTP error code

    • message string

      Error message

    • data object
      Hide data attributes Show data attributes object
      • type string

        Type of error

        Values are validation_error or external_api_error.

      • errors array[object]
        Hide errors attributes Show errors attributes object
        • key string

          Field name that failed validation

        • message string

          Error code or message

        • value string

          Value that failed validation

      • details

        Additional error details

  • 401 application/json

    Unauthorized - invalid or missing token

    Hide response attributes Show response attributes object
    • code integer
    • message string
    • data object | null
  • 403 application/json

    Forbidden - insufficient permissions

    Hide response attributes Show response attributes object
    • code integer
    • message string
    • data object | null
  • 404 application/json

    Resource not found

    Hide response attributes Show response attributes object
    • code integer

      HTTP error code

    • message string

      Error message

    • data object
      Hide data attributes Show data attributes object
      • type string

        Type of error

        Values are validation_error or external_api_error.

      • errors array[object]
        Hide errors attributes Show errors attributes object
        • key string

          Field name that failed validation

        • message string

          Error code or message

        • value string

          Value that failed validation

      • details

        Additional error details

  • 409 application/json

    The organization cannot be promoted in its current state. Same validation_error shape as the 400, on key promote, with stable message codes: organization_is_suspended (reactivate it first), organization_not_synced (no Logto organization yet), owner_organization_not_found (no Owner organization to attach it to).

    Hide response attributes Show response attributes object
    • code integer

      HTTP error code

    • message string

      Error message

    • data object
      Hide data attributes Show data attributes object
      • type string

        Type of error

        Values are validation_error or external_api_error.

      • errors array[object]
        Hide errors attributes Show errors attributes object
        • key string

          Field name that failed validation

        • message string

          Error code or message

        • value string

          Value that failed validation

      • details

        Additional error details

PATCH /resellers/{id}/promote
curl \
 --request PATCH 'https://api.your-domain.com/api/resellers/{id}/promote' \
 --header "Authorization: Bearer $ACCESS_TOKEN"
Response examples (200)
{
  "code": 200,
  "message": "reseller promoted to distributor successfully",
  "data": {
    "distributor": {
      "id": "4405ffd0-0aca-44ef-bae2-c8545bce94f4",
      "logto_id": "akkbs6x2wo82",
      "name": "ACME Distribution SpA",
      "description": "Main distributor for Italian and Swiss markets",
      "custom_data": {
        "email": "contact@acme-distribution.com",
        "contactPerson": "John Smith",
        "region": "Italy"
      },
      "suspended_at": "2026-05-04T09:42:00Z",
      "suspended_by_org_id": "string",
      "rebranding_enabled": false,
      "rebranding_org_id": "string",
      "created_by": {
        "user_id": "aa15fcvgzw1y",
        "username": "owner",
        "name": "Nethesis Owner",
        "email": "owner@nethesis.it",
        "organization_id": "2wl3iixbc8ua",
        "organization_name": "Owner",
        "on_behalf_of": true
      }
    },
    "detached_from_organization_id": "5j8k2m4n6p8q",
    "parent_organization_id": "aa15fcvgzw1y",
    "customers_count": 12,
    "users_count": 3,
    "systems_count": 4,
    "members_role_switched": 3,
    "warnings": [
      "string"
    ]
  }
}
Response examples (400)
{
  "code": 400,
  "message": "validation failed",
  "data": {
    "type": "validation_error",
    "errors": [
      {
        "key": "custom_data.vat",
        "message": "already exists",
        "value": "12345678901"
      }
    ]
  }
}
Response examples (401)
{
  "code": 401,
  "message": "invalid token",
  "data": {}
}
Response examples (403)
{
  "code": 403,
  "message": "insufficient permissions",
  "data": {}
}
Response examples (404)
{
  "code": 400,
  "message": "validation failed",
  "data": {
    "type": "validation_error",
    "errors": [
      {
        "key": "username",
        "message": "required",
        "value": "string"
      }
    ]
  }
}
Response examples (409)
{
  "code": 409,
  "message": "validation failed",
  "data": {
    "type": "validation_error",
    "errors": [
      {
        "key": "promote",
        "message": "organization_is_suspended"
      }
    ]
  }
}