{
  "openapi": "3.0.3",
  "info": {
    "title": "Access Token API",
    "version": "0.4.0",
    "description": "Generate Access Tokens for 3rd party applications that need access to epilot APIs.\n"
  },
  "tags": [
    {
      "name": "Access Tokens",
      "description": "Create Access Tokens for epilot APIs"
    },
    {
      "name": "Public",
      "description": "Well known endpoints to verify tokens generated by this API"
    }
  ],
  "security": [
    {
      "EpilotAuth": []
    },
    {
      "EpilotOrg": []
    }
  ],
  "paths": {
    "/v1/access-tokens": {
      "post": {
        "operationId": "createAccessToken",
        "summary": "createAccessToken",
        "description": "**Access Token type: `API`** (default if not specified):\n\nGenerates a new Access Token to use for calling epilot APIs.\n\nTakes optionally a list of Roles assigned to the Access Token. Defaults to current user's assignments\n\nSee [Permissions API docs](https://docs.epilot.io/api/permissions)\n\n**Access Token type: `JOURNEY`**:\n\nGenerates a Public Access Token related to a journey.\nThe journey id should be specfied.\n",
        "tags": [
          "Access Tokens"
        ],
        "requestBody": {
          "description": "Metadata for the Access Token",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TokenParameters"
              },
              "examples": {
                "api": {
                  "value": {
                    "name": "API Access Token",
                    "token_type": "api",
                    "assignments": []
                  }
                },
                "journey": {
                  "value": {
                    "name": "Journey Access Token",
                    "token_type": "journey",
                    "journey_id": "u29g7-97gajsaog-028t02jag-a9a72tk"
                  }
                },
                "portal": {
                  "value": {
                    "name": "Installer /End Customer Portal Access Token",
                    "token_type": "portal",
                    "portal_id": "END_CUSTOMER_PORTAL"
                  }
                },
                "assume": {
                  "value": {
                    "name": "Assume Token intended for assuming a different role as a user",
                    "token_type": "assume",
                    "assignments": [
                      "739224:employee"
                    ]
                  }
                },
                "portal_preview": {
                  "value": {
                    "name": "Portal Preview Token for previewing customer portal",
                    "token_type": "portal_preview",
                    "portal_id": "portal_abc123",
                    "portal_user_id": "user_xyz789"
                  }
                },
                "app": {
                  "value": {
                    "name": "App Access Token",
                    "token_type": "app",
                    "assignments": [
                      "739224:e5c1f9b1-e41d-421d-83c4-c5626e464430"
                    ]
                  }
                },
                "contact_identification": {
                  "value": {
                    "name": "Contact Identification Token",
                    "token_type": "contact_identification",
                    "portal_id": "portal_abc123",
                    "contact_id": "5da0a718-c822-403d-9f5d-20d4584e0528",
                    "surface_id": "website-journeys",
                    "allowed_operations": [
                      "getContact",
                      "getContracts"
                    ],
                    "expires_in": 300
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The new generated Access Token",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "properties": {
                        "token": {
                          "$ref": "#/components/schemas/AccessToken"
                        }
                      }
                    },
                    {
                      "$ref": "#/components/schemas/AccessTokenItem"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal Server Error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "integer"
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listAccessTokens",
        "summary": "listAccessTokens",
        "description": "Lists all Access Tokens for current user (by default excludes system generated tokens)",
        "parameters": [
          {
            "in": "query",
            "name": "token_type",
            "description": "Filter by token types",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/AccessTokenType"
              }
            }
          }
        ],
        "tags": [
          "Access Tokens"
        ],
        "responses": {
          "200": {
            "description": "List of Access Tokens",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AccessTokenItem"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/access-tokens/{id}": {
      "delete": {
        "operationId": "revokeAccessToken",
        "summary": "revokeAccessToken",
        "description": "Revokes an Access Token so it can't be used anymore.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "schema": {
              "$ref": "#/components/schemas/AccessTokenId"
            },
            "required": true
          }
        ],
        "tags": [
          "Access Tokens"
        ],
        "responses": {
          "200": {
            "description": "The revoked generated Access Token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccessTokenItem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/access-tokens/.well-known/jwks.json": {
      "get": {
        "operationId": "getAccessTokenJwks",
        "summary": "getAccessTokenJwks",
        "description": "Get jwks public key set to verify access tokens generated by this API",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Set of jwks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "alg": {
                            "type": "string",
                            "example": "RS256"
                          },
                          "e": {
                            "type": "string",
                            "example": "AQAB"
                          },
                          "kid": {
                            "type": "string",
                            "example": "tXWU5mPMbRPczpbQwi6vbhLF4GgF3wlMDSyqo7pfeiw="
                          },
                          "kty": {
                            "type": "string",
                            "example": "RSA"
                          },
                          "n": {
                            "type": "string",
                            "example": "h_QDoCjZ8W_trtYXaP7_S22wf5r5Wd9XBLED78oT44bJjQXn8ddcFV8Hik65_4IYXVX_hTTU4zpxe3H8vx2j7-Zz3O59mYMp5S0MzODNEdf5Y_2o19eis0brmAJniixsNlQ9LlYkdrVamrgaxHu3ZpP_99zkfFybYeuYoQNzb3PyrT8xVnz_USs_nlFMHpGUxvvz7gfKPqxcLvgLJr4cwI9yzaSY9CD4qW181QVcnL_WzpQ8xx6AuhhHZQ1l_3GG4InTk8ahE7U2ZHVu8RrX6d01pMgc3piEcet9RgFLnhbTg3YIiKGoAbN42wJn_x3lgIAC42T9mbmTsHyUdS6nUQ"
                          },
                          "use": {
                            "type": "string",
                            "example": "sig"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/access-tokens/.well-known/openid-configuration": {
      "get": {
        "operationId": "getAccessTokenOIDC",
        "summary": "getAccessTokenOIDC",
        "description": "OpenID Connect configuration for Access Token API as identity provider\n\nNote: This API is not a fully compliant OAuth2.0 / OIDC identity provider, but this endpoint is useful to\nautomate the process of verifying JWT tokens.\n",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OpenID Configuration",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "issuer": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://access-token.sls.epilot.io/v1/access-tokens"
                    },
                    "jwks_uri": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://access-token.sls.epilot.io/v1/access-tokens/.well-known/jwks.json"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/access-tokens/public/.well-known/jwks.json": {
      "get": {
        "operationId": "getPublicTokenJwks",
        "summary": "getPublicTokenJwks",
        "description": "Get jwks public key set to verify public tokens generated by this API",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Set of jwks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "alg": {
                            "type": "string",
                            "example": "RS256"
                          },
                          "e": {
                            "type": "string",
                            "example": "AQAB"
                          },
                          "kid": {
                            "type": "string",
                            "example": "tXWU5mPMbRPczpbQwi6vbhLF4GgF3wlMDSyqo7pfeiw="
                          },
                          "kty": {
                            "type": "string",
                            "example": "RSA"
                          },
                          "n": {
                            "type": "string",
                            "example": "h_QDoCjZ8W_trtYXaP7_S22wf5r5Wd9XBLED78oT44bJjQXn8ddcFV8Hik65_4IYXVX_hTTU4zpxe3H8vx2j7-Zz3O59mYMp5S0MzODNEdf5Y_2o19eis0brmAJniixsNlQ9LlYkdrVamrgaxHu3ZpP_99zkfFybYeuYoQNzb3PyrT8xVnz_USs_nlFMHpGUxvvz7gfKPqxcLvgLJr4cwI9yzaSY9CD4qW181QVcnL_WzpQ8xx6AuhhHZQ1l_3GG4InTk8ahE7U2ZHVu8RrX6d01pMgc3piEcet9RgFLnhbTg3YIiKGoAbN42wJn_x3lgIAC42T9mbmTsHyUdS6nUQ"
                          },
                          "use": {
                            "type": "string",
                            "example": "sig"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/access-tokens/portal-preview/.well-known/jwks.json": {
      "get": {
        "operationId": "getPortalPreviewTokenJwks",
        "summary": "getPortalPreviewTokenJwks",
        "description": "Get jwks public key set to verify portal preview tokens generated by this API",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Set of jwks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "alg": {
                            "type": "string",
                            "example": "RS256"
                          },
                          "e": {
                            "type": "string",
                            "example": "AQAB"
                          },
                          "kid": {
                            "type": "string",
                            "example": "tXWU5mPMbRPczpbQwi6vbhLF4GgF3wlMDSyqo7pfeiw="
                          },
                          "kty": {
                            "type": "string",
                            "example": "RSA"
                          },
                          "n": {
                            "type": "string",
                            "example": "h_QDoCjZ8W_trtYXaP7_S22wf5r5Wd9XBLED78oT44bJjQXn8ddcFV8Hik65_4IYXVX_hTTU4zpxe3H8vx2j7-Zz3O59mYMp5S0MzODNEdf5Y_2o19eis0brmAJniixsNlQ9LlYkdrVamrgaxHu3ZpP_99zkfFybYeuYoQNzb3PyrT8xVnz_USs_nlFMHpGUxvvz7gfKPqxcLvgLJr4cwI9yzaSY9CD4qW181QVcnL_WzpQ8xx6AuhhHZQ1l_3GG4InTk8ahE7U2ZHVu8RrX6d01pMgc3piEcet9RgFLnhbTg3YIiKGoAbN42wJn_x3lgIAC42T9mbmTsHyUdS6nUQ"
                          },
                          "use": {
                            "type": "string",
                            "example": "sig"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/access-tokens/public/.well-known/openid-configuration": {
      "get": {
        "operationId": "getPublicTokenOIDC",
        "summary": "getPublicTokenOIDC",
        "description": "OpenID Connect configuration for Access Token API a a public identity provider\n\nNote: This API is not a fully compliant OAuth2.0 / OIDC identity provider, but this endpoint is useful to\nautomate the process of verifying JWT tokens.\n",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OpenID Configuration",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "issuer": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://access-token.sls.epilot.io/v1/access-tokens"
                    },
                    "jwks_uri": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://access-token.sls.epilot.io/v1/access-tokens/.well-known/jwks.json"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/access-tokens/portal-preview/.well-known/openid-configuration": {
      "get": {
        "operationId": "getPortalPreviewTokenOIDC",
        "summary": "getPortalPreviewTokenOIDC",
        "description": "OpenID Connect configuration for Access Token API a a portal preview identity provider\n\nNote: This API is not a fully compliant OAuth2.0 / OIDC identity provider, but this endpoint is useful to\nautomate the process of verifying JWT tokens.\n",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OpenID Configuration",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "issuer": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://access-token.sls.epilot.io/v1/access-tokens/portal-preview"
                    },
                    "jwks_uri": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://access-token.sls.epilot.io/v1/access-tokens/portal-preview/.well-known/jwks.json"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/access-tokens/contact-identification/.well-known/jwks.json": {
      "get": {
        "operationId": "getContactIdentificationTokenJwks",
        "summary": "getContactIdentificationTokenJwks",
        "description": "Get jwks public key set to verify contact identification tokens generated by this API",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Set of jwks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "alg": {
                            "type": "string",
                            "example": "RS256"
                          },
                          "e": {
                            "type": "string",
                            "example": "AQAB"
                          },
                          "kid": {
                            "type": "string",
                            "example": "tXWU5mPMbRPczpbQwi6vbhLF4GgF3wlMDSyqo7pfeiw="
                          },
                          "kty": {
                            "type": "string",
                            "example": "RSA"
                          },
                          "n": {
                            "type": "string",
                            "example": "h_QDoCjZ8W_trtYXaP7_S22wf5r5Wd9XBLED78oT44bJjQXn8ddcFV8Hik65_4IYXVX_hTTU4zpxe3H8vx2j7-Zz3O59mYMp5S0MzODNEdf5Y_2o19eis0brmAJniixsNlQ9LlYkdrVamrgaxHu3ZpP_99zkfFybYeuYoQNzb3PyrT8xVnz_USs_nlFMHpGUxvvz7gfKPqxcLvgLJr4cwI9yzaSY9CD4qW181QVcnL_WzpQ8xx6AuhhHZQ1l_3GG4InTk8ahE7U2ZHVu8RrX6d01pMgc3piEcet9RgFLnhbTg3YIiKGoAbN42wJn_x3lgIAC42T9mbmTsHyUdS6nUQ"
                          },
                          "use": {
                            "type": "string",
                            "example": "sig"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/access-tokens/contact-identification/.well-known/openid-configuration": {
      "get": {
        "operationId": "getContactIdentificationTokenOIDC",
        "summary": "getContactIdentificationTokenOIDC",
        "description": "OpenID Connect configuration for Access Token API as a contact identification identity provider\n\nNote: This API is not a fully compliant OAuth2.0 / OIDC identity provider, but this endpoint is useful to\nautomate the process of verifying JWT tokens.\n",
        "tags": [
          "Public"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "OpenID Configuration",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "issuer": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://access-token.sls.epilot.io/v1/access-tokens/contact-identification"
                    },
                    "jwks_uri": {
                      "type": "string",
                      "format": "uri",
                      "example": "https://access-token.sls.epilot.io/v1/access-tokens/contact-identification/.well-known/jwks.json"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "EpilotAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization header with epilot OAuth2 bearer token",
        "bearerFormat": "JWT"
      },
      "EpilotOrg": {
        "description": "Overrides the target organization to allow shared tenantaccess",
        "name": "x-epilot-org-id",
        "in": "header",
        "type": "apiKey"
      }
    },
    "schemas": {
      "AccessToken": {
        "type": "string",
        "description": "A JWT Access Token",
        "example": "eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp..."
      },
      "AccessTokenId": {
        "type": "string",
        "example": "api_5ZugdRXasLfWBypHi93Fk"
      },
      "AccessTokenName": {
        "type": "string",
        "description": "Human readable name for access token",
        "example": "Postman Access Token"
      },
      "AccessTokenType": {
        "type": "string",
        "enum": [
          "api",
          "journey",
          "portal",
          "assume",
          "app",
          "portal_preview",
          "contact_identification"
        ],
        "description": "Access token type",
        "example": "api"
      },
      "AccessTokenJourneyId": {
        "type": "string",
        "description": "Journey ID for access token type \"journey\""
      },
      "PortalId": {
        "type": "string",
        "description": "Portal ID for access token type \"portal\""
      },
      "PortalUserId": {
        "type": "string",
        "description": "Portal User ID for access token type \"portal_preview\""
      },
      "ContactId": {
        "type": "string",
        "description": "Contact entity ID for access token type \"contact_identification\"",
        "example": "5da0a718-c822-403d-9f5d-20d4584e0528"
      },
      "AllowedOperations": {
        "type": "array",
        "description": "openapi operationIds the token may call. Enforced by the API that consumes the token, which must additionally deny any operation not on this list. Baked into the token at issue time so widening the consumer's own allowlist later cannot retroactively widen a token that is already in circulation.",
        "items": {
          "type": "string"
        },
        "example": [
          "getContact",
          "getContracts"
        ]
      },
      "TokenParameters": {
        "anyOf": [
          {
            "$ref": "#/components/schemas/AccessTokenParameters"
          },
          {
            "$ref": "#/components/schemas/JourneyTokenParameters"
          },
          {
            "$ref": "#/components/schemas/PortalTokenParameters"
          },
          {
            "$ref": "#/components/schemas/AssumeTokenParameters"
          },
          {
            "$ref": "#/components/schemas/AppTokenParameters"
          },
          {
            "$ref": "#/components/schemas/PortalPreviewTokenParameters"
          },
          {
            "$ref": "#/components/schemas/ContactIdentificationTokenParameters"
          }
        ]
      },
      "ExpiresIn": {
        "oneOf": [
          {
            "type": "integer",
            "format": "int32",
            "description": "Expiration time in seconds. api tokens may live up to 365 days (31536000); all other token types are capped at 7 days (604800) server-side.",
            "example": 3600,
            "minimum": 30,
            "maximum": 31536000
          },
          {
            "type": "string",
            "description": "Expiration time as a string with time units (e.g., '10h', '7d', '2 days')",
            "example": "1h",
            "pattern": "^[0-9]+ ?(ms|milliseconds?|s|seconds?|m|minutes?|h|hours?|d|days?|w|weeks?|y|years?)?$"
          }
        ]
      },
      "ReadOnly": {
        "type": "boolean",
        "description": "When true, the issued token may only perform read-only actions. Any action guarded by permissions that is not read-only (i.e. not a view/export/download action) is denied, regardless of the roles the token carries.",
        "example": true
      },
      "Anonymize": {
        "type": "boolean",
        "default": false,
        "description": "Forces PII anonymization on all entity data returned to this token. Cannot be disabled by the token bearer. See entity-api anonymized responses.",
        "example": true
      },
      "AccessTokenParameters": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "$ref": "#/components/schemas/AccessTokenName"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "api"
            ]
          },
          "assignments": {
            "$ref": "#/components/schemas/Assignments"
          },
          "expires_in": {
            "$ref": "#/components/schemas/ExpiresIn"
          },
          "read_only": {
            "$ref": "#/components/schemas/ReadOnly"
          },
          "anonymize": {
            "$ref": "#/components/schemas/Anonymize"
          }
        },
        "required": [
          "name"
        ]
      },
      "JourneyTokenParameters": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "$ref": "#/components/schemas/AccessTokenName"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "journey"
            ]
          },
          "journey_id": {
            "$ref": "#/components/schemas/AccessTokenJourneyId"
          },
          "expires_in": {
            "$ref": "#/components/schemas/ExpiresIn"
          }
        },
        "required": [
          "name",
          "journey_id"
        ]
      },
      "PortalTokenParameters": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "$ref": "#/components/schemas/AccessTokenName"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "portal"
            ]
          },
          "portal_id": {
            "$ref": "#/components/schemas/PortalId"
          },
          "expires_in": {
            "$ref": "#/components/schemas/ExpiresIn"
          }
        },
        "required": [
          "name",
          "portal_id"
        ]
      },
      "AssumeTokenParameters": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "$ref": "#/components/schemas/AccessTokenName"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "assume"
            ]
          },
          "assignments": {
            "$ref": "#/components/schemas/Assignments"
          },
          "read_only": {
            "$ref": "#/components/schemas/ReadOnly"
          },
          "anonymize": {
            "$ref": "#/components/schemas/Anonymize"
          }
        },
        "required": [
          "name"
        ]
      },
      "AppTokenParameters": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "$ref": "#/components/schemas/AccessTokenName"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "app"
            ]
          },
          "assignments": {
            "$ref": "#/components/schemas/Assignments"
          },
          "expires_in": {
            "$ref": "#/components/schemas/ExpiresIn"
          },
          "read_only": {
            "$ref": "#/components/schemas/ReadOnly"
          },
          "anonymize": {
            "$ref": "#/components/schemas/Anonymize"
          }
        },
        "required": [
          "name"
        ]
      },
      "PortalPreviewTokenParameters": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "name": {
            "$ref": "#/components/schemas/AccessTokenName"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "portal_preview"
            ]
          },
          "portal_id": {
            "$ref": "#/components/schemas/PortalId"
          },
          "portal_user_id": {
            "$ref": "#/components/schemas/PortalUserId"
          }
        },
        "required": [
          "name",
          "portal_id",
          "portal_user_id"
        ]
      },
      "ContactIdentificationTokenParameters": {
        "type": "object",
        "additionalProperties": false,
        "description": "A token that acts as one contact, issued after that contact was identified by a portal's registration identifiers rather than by logging in. Distinct from portal_preview, which impersonates an existing portal user for a 360 operator: this kind belongs to no user, is minted for an unauthenticated caller, and is therefore always short-lived and restricted to an explicit operation allowlist. Never stored, so it cannot be listed or revoked - keep expires_in short.",
        "properties": {
          "name": {
            "$ref": "#/components/schemas/AccessTokenName"
          },
          "token_type": {
            "type": "string",
            "enum": [
              "contact_identification"
            ]
          },
          "portal_id": {
            "$ref": "#/components/schemas/PortalId"
          },
          "contact_id": {
            "$ref": "#/components/schemas/ContactId"
          },
          "surface_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64,
            "description": "Portal surface the token is issued for (see `surfaces` on the portal config in customer-portal-api). Carried as the `custom:surface_id` claim; the consuming API resolves the surface's data access from the portal config on every request.",
            "example": "website-journeys"
          },
          "allowed_operations": {
            "$ref": "#/components/schemas/AllowedOperations"
          },
          "expires_in": {
            "type": "integer",
            "format": "int32",
            "minimum": 60,
            "maximum": 900,
            "description": "Lifetime in seconds. Integer only for this token type (no \"5m\" strings), and capped server-side by CONTACT_IDENTIFICATION_TOKEN_MAX_EXPIRATION_SECONDS - the value originates from portal configuration, so it is not trusted as-is.",
            "example": 300
          },
          "email": {
            "type": "string",
            "description": "Optional. Carried as the `email` claim when the consumer needs it (e.g. to attribute an activity). Omit to keep the contact's email out of the token."
          }
        },
        "required": [
          "name",
          "portal_id",
          "contact_id",
          "surface_id",
          "allowed_operations",
          "expires_in"
        ]
      },
      "AccessTokenItem": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/AccessTokenId"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "name": {
            "$ref": "#/components/schemas/AccessTokenName"
          },
          "token_type": {
            "$ref": "#/components/schemas/AccessTokenType"
          },
          "journey_id": {
            "$ref": "#/components/schemas/AccessTokenJourneyId"
          },
          "portal_id": {
            "$ref": "#/components/schemas/PortalId"
          },
          "portal_user_id": {
            "$ref": "#/components/schemas/PortalUserId"
          },
          "contact_id": {
            "$ref": "#/components/schemas/ContactId"
          },
          "allowed_operations": {
            "$ref": "#/components/schemas/AllowedOperations"
          },
          "assignments": {
            "$ref": "#/components/schemas/Assignments"
          },
          "read_only": {
            "$ref": "#/components/schemas/ReadOnly"
          },
          "anonymize": {
            "$ref": "#/components/schemas/Anonymize"
          },
          "last_used": {
            "type": "string",
            "format": "date",
            "description": "Last date the token was used (YYYY-MM-DD format, 1 day accuracy)",
            "example": "2026-02-24"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "description": "Timestamp when the token expires and stops being accepted (only set for tokens created with expires_in)",
            "example": "2026-03-01T12:00:00.000Z"
          }
        },
        "required": [
          "id",
          "created_at",
          "name"
        ]
      },
      "RoleId": {
        "type": "string",
        "example": "123:owner",
        "description": "Format: <organization_id>:<slug>"
      },
      "Assignments": {
        "type": "array",
        "description": "List of role ids attached to an user",
        "items": {
          "$ref": "#/components/schemas/RoleId"
        }
      }
    }
  },
  "servers": [
    {
      "url": "https://access-token.sls.epilot.io"
    }
  ]
}
