{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/easy2257-com/json-schema/easy2257-com-collab-scene-response-schema.json",
  "title": "CollabSceneResponse",
  "x-generated": "2026-11-06",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/easy2257-com-openapi.yml#/components/schemas/CollabSceneResponse",
  "type": "object",
  "properties": {
    "sceneId": {
      "type": "string"
    },
    "status": {
      "type": "string",
      "enum": [
        "pending_signatures",
        "greenlit",
        "blocked",
        "cancelled"
      ],
      "description": "`pending_signatures`: waiting on performers. `greenlit`: everyone signed and every new performer passed ID verification. This is the only status that permits publication. `blocked`: a performer refused, or the 14-day window lapsed. `cancelled`: cancelled through the API. No refund."
    },
    "performers": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "format": "email"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_consent",
              "consented",
              "refused"
            ],
            "description": "`pending_consent`: invited, has not yet signed. This one value covers every unsigned performer, whether or not the address already had an Easy2257 account: registration and ID verification, when needed, happen inside the magic-link flow and are never visible here, so performer status cannot be used to probe whether an email is already on Easy2257. `consented`: release signed and consent recorded. `refused`: performer declined, which blocks the scene. When the signing window lapses, the scene flips to `blocked` while unsigned performers stay `pending_consent`."
          }
        },
        "required": [
          "email",
          "status"
        ],
        "description": "Email and status, nothing else. There is deliberately no per-performer flag saying whether the address already had an Easy2257 account: that would be an account-existence oracle on arbitrary emails."
      }
    },
    "fees": {
      "type": "object",
      "properties": {
        "sceneFeeCents": {
          "type": "integer",
          "description": "Base scene record fee, 500 cents."
        },
        "onboardingFeeCents": {
          "type": "integer",
          "description": "2500 cents for each performer who did not already have an active Easy2257 solo account or an approved ID check from a collab scene in the last 12 months. Performers who hold either add nothing: the fee is once per person, not once per scene. The split is an aggregate for the whole scene; it is not itemized per performer."
        },
        "totalCents": {
          "type": "integer"
        },
        "charged": {
          "type": "boolean",
          "description": "true once a Stripe charge id is on the record. The scene is created either way: a billing failure does not block consent collection, so check this rather than assuming payment succeeded. On `billedTo: platform_invoice` it stays false: the fees are collected with your monthly platform invoice."
        },
        "stripeChargeId": {
          "type": [
            "string",
            "null"
          ],
          "description": "Despite the field name this holds the Stripe PaymentIntent id, charged off-session against the uploader's saved payment method. null when `billedTo` is `platform_invoice`."
        },
        "billedTo": {
          "type": "string",
          "enum": [
            "uploader_card",
            "platform_invoice"
          ],
          "description": "Who pays the fees. `uploader_card`: charged off-session to the uploading creator's saved card. `platform_invoice`: a platform-funded account with collab scenes switched on; the fees are added to your platform's next monthly invoice, so `charged` stays false and `stripeChargeId` null."
        },
        "chargeError": {
          "type": [
            "string",
            "null"
          ],
          "description": "null when the immediate off-session charge succeeded or nothing was due. Otherwise a free-form failure code, not a fixed enum: for example `no_payment_method`, `card_declined`, or `payment_requires_action`. The scene is still created and consent collection proceeds; the fee is settled on the billing side. On `billedTo: platform_invoice` it reports a failure to add the fees to your invoice: the scene still stands and Easy2257 is alerted to add them by hand."
        }
      },
      "required": [
        "sceneFeeCents",
        "onboardingFeeCents",
        "totalCents",
        "charged",
        "stripeChargeId",
        "billedTo",
        "chargeError"
      ]
    },
    "expiresAt": {
      "type": "string",
      "format": "date-time",
      "description": "14 days from creation. Unsigned at that point and the scene is blocked."
    }
  },
  "required": [
    "sceneId",
    "status",
    "performers",
    "fees",
    "expiresAt"
  ]
}