{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://yougrow.ai/developers/schema/user.json",
  "title": "User",
  "description": "A user as GET /api/v2/users/{userId} returns them: their state, their journeys and their opt-outs.",
  "type": "object",
  "properties": {
    "userId": {
      "type": "string",
      "description": "Your id for the user."
    },
    "email": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "As you last sent it; `null` if you haven't."
    },
    "firstName": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "As you last sent it; `null` if you haven't."
    },
    "lastName": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "As you last sent it; `null` if you haven't."
    },
    "timezone": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "As you last sent it; `null` if you haven't."
    },
    "locale": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "As you last sent it; `null` if you haven't."
    },
    "signedUpAt": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "When the account was created, in UTC; `null` if you haven't sent it."
    },
    "consent": {
      "anyOf": [
        {
          "type": "string",
          "enum": [
            "consent",
            "soft_opt_in",
            "corporate_subscriber",
            "none"
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "The legal basis you sent."
    },
    "subscribed": {
      "type": "boolean",
      "description": "`false` while they're opted out in your product. Unsubscribes made in our emails are in `optOuts` (GET only)."
    },
    "excluded": {
      "anyOf": [
        {
          "type": "object",
          "properties": {
            "reason": {
              "type": "string"
            }
          },
          "required": [
            "reason"
          ]
        },
        {
          "type": "null"
        }
      ],
      "description": "Set while they're excluded from every journey."
    },
    "steps": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": "string"
      },
      "maxProperties": 50,
      "description": "Step id → when it was done, in UTC."
    },
    "facts": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 200
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          }
        ]
      },
      "maxProperties": 50,
      "description": "Fact id → the latest value you sent."
    },
    "traits": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 500
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          }
        ]
      },
      "maxProperties": 50,
      "description": "Trait key → value."
    },
    "entities": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "parentId": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "role": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "owner",
                  "member",
                  "invited"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "steps": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "string"
            },
            "maxProperties": 50
          },
          "facts": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                }
              ]
            },
            "maxProperties": 50
          },
          "activeAt": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "kind",
          "name",
          "parentId",
          "role",
          "steps",
          "facts",
          "activeAt"
        ]
      },
      "description": "Entity id → its kind, name, parent, role, steps, facts and when they last worked on it."
    },
    "updatedAt": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "description": "The newest `updatedAt` applied, or `null` if you've never sent one."
    },
    "enrolments": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "journeyId": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "mode": {
            "type": "string"
          },
          "enrolledAt": {
            "type": "string"
          },
          "entityId": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "journeyId",
          "status",
          "mode",
          "enrolledAt"
        ]
      },
      "description": "The journeys they're in or have been through: the journey's id, `status` (`active`, `completed` or `exited`), `mode` (`test`, `shadow` or `live`), when they joined, and `entityId` when the journey is about one of their entities."
    },
    "optOuts": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "scope": {
            "type": "string",
            "enum": [
              "all",
              "category"
            ]
          },
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "scope",
          "category",
          "at"
        ]
      },
      "description": "Unsubscribes made in YouGrow's emails: `scope` `all` or `category` (with the `category`), and when. The API can't lift them, and `subscribed: true` doesn't either."
    }
  },
  "required": [
    "userId",
    "email",
    "firstName",
    "lastName",
    "timezone",
    "locale",
    "signedUpAt",
    "consent",
    "subscribed",
    "excluded",
    "steps",
    "facts",
    "traits",
    "entities",
    "updatedAt",
    "enrolments",
    "optOuts"
  ]
}
