changedOutput schema / (root)
Previous value: -nullNew value: +{
+ "$defs": {
+ "IntegrationFollowing": {
+ "additionalProperties": false,
+ "description": "What the account follows and can still follow. Following decides which markets can be read; it happens in the Kunkafa app.",
+ "properties": {
+ "canFollow": {
+ "description": "Whether this connection may follow and unfollow markets.",
+ "type": "boolean"
+ },
+ "canFollowMore": {
+ "description": "How many more markets can be followed; null when the account reads every market.",
+ "minimum": 0,
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "followInApp": {
+ "description": "Where the user follows markets in the Kunkafa app.",
+ "format": "uri",
+ "type": "string"
+ },
+ "followLimit": {
+ "description": "The plan's Following count; null when the account reads every market.",
+ "minimum": 0,
+ "type": [
+ "integer",
+ "null"
+ ]
+ },
+ "followed": {
+ "description": "Markets on the account's following list, as the app counts them.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "howToAllowFollowing": {
+ "description": "Present when canFollow is false.",
+ "minLength": 1,
+ "type": "string"
+ },
+ "message": {
+ "description": "Plain explanation for the user, including for accounts that read every market.",
+ "type": "string"
+ },
+ "otherMarkets": {
+ "description": "Catalogue markets the account does not follow, by English name, sorted by name; at most 100 (otherMarketsTotal gives the full count). Any market can still be followed by its slug.",
+ "items": {
+ "additionalProperties": false,
+ "properties": {
+ "market": {
+ "$ref": "#/$defs/IntegrationMarketSlug"
+ },
+ "name": {
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "required": [
+ "market",
+ "name"
+ ],
+ "type": "object"
+ },
+ "maxItems": 100,
+ "type": "array"
+ },
+ "otherMarketsTotal": {
+ "description": "How many catalogue markets the account does not follow.",
+ "minimum": 0,
+ "type": "integer"
+ },
+ "readsEveryMarket": {
+ "type": "boolean"
+ }
+ },
+ "required": [
+ "followed",
+ "followLimit",
+ "canFollowMore",
+ "readsEveryMarket",
+ "message",
+ "followInApp",
+ "otherMarkets",
+ "otherMarketsTotal"
+ ],
+ "type": "object"
+ },
+ "IntegrationMarketSlug": {
+ "description": "Published English-name market slug returned by authorized discovery.",
+ "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
+ "type": "string"
+ },
+ "IntegrationNotice": {
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "kind": {
+ "enum": [
+ "approaching_limit",
+ "limit_reached"
+ ]
+ },
+ "limit": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "message": {
+ "type": "string"
+ },
+ "nextCapacityAt": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/IntegrationTimestamp"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "period": {
+ "enum": [
+ "day",
+ "week",
+ "month"
+ ]
+ },
+ "remaining": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "used": {
+ "minimum": 0,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "id",
+ "period",
+ "kind",
+ "message",
+ "used",
+ "limit",
+ "remaining",
+ "nextCapacityAt"
+ ],
+ "type": "object"
+ },
+ "IntegrationPage": {
+ "additionalProperties": false,
+ "description": "Follow nextCursor until null. Cursors are invalidated by relevant access or market-list changes; restart without a cursor.",
+ "properties": {
+ "nextCursor": {
+ "anyOf": [
+ {
+ "maxLength": 256,
+ "minLength": 1,
+ "pattern": "^[A-Za-z0-9_-]+$",
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "returned": {
+ "maximum": 50,
+ "minimum": 0,
+ "type": "integer"
+ },
+ "total": {
+ "minimum": 0,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "total",
+ "returned",
+ "nextCursor"
+ ],
+ "type": "object"
+ },
+ "IntegrationTimestamp": {
+ "description": "ISO 8601 UTC timestamp supplied by Kunkafa.",
+ "format": "date-time",
+ "type": "string"
+ },
+ "IntegrationUsage": {
+ "additionalProperties": false,
+ "properties": {
+ "adjustment": {
+ "additionalProperties": false,
+ "description": "An owner-approved account allowance increase. A null expiration is permanent until changed. Usage is never reset; market access and credential eligibility still follow the current plan.",
+ "properties": {
+ "expiresAt": {
+ "format": "date-time",
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ },
+ "required": [
+ "expiresAt"
+ ],
+ "type": "object"
+ },
+ "calculatedAt": {
+ "$ref": "#/$defs/IntegrationTimestamp"
+ },
+ "concurrency": {
+ "additionalProperties": false,
+ "description": "Private requests that can run at the same time. Requests from one connection run side by side up to this limit (the plan burst); a request from another connection waits until they finish.",
+ "properties": {
+ "limit": {
+ "maximum": 100,
+ "minimum": 1,
+ "type": "integer"
+ },
+ "nextRequestAt": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/IntegrationTimestamp"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "remaining": {
+ "maximum": 100,
+ "minimum": 0,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "limit",
+ "remaining",
+ "nextRequestAt"
+ ],
+ "type": "object"
+ },
+ "requests": {
+ "additionalProperties": false,
+ "description": "Steady request rate with bounded burst capacity; metadata and repeated summaries still count toward request protection.",
+ "properties": {
+ "burst": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "nextRequestAt": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/IntegrationTimestamp"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "perMinute": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "remaining": {
+ "minimum": 0,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "perMinute",
+ "burst",
+ "remaining",
+ "nextRequestAt"
+ ],
+ "type": "object"
+ },
+ "tier": {
+ "enum": [
+ "free",
+ "starter",
+ "core",
+ "pro",
+ "publisher"
+ ]
+ },
+ "windows": {
+ "items": {
+ "$ref": "#/$defs/IntegrationWindowUsage"
+ },
+ "maxItems": 3,
+ "minItems": 3,
+ "type": "array"
+ }
+ },
+ "required": [
+ "calculatedAt",
+ "tier",
+ "requests",
+ "concurrency",
+ "windows"
+ ],
+ "type": "object"
+ },
+ "IntegrationWindowUsage": {
+ "additionalProperties": false,
+ "description": "Rolling 24-hour, 7-day or 30-day allowance, not a midnight reset. Used can exceed the current limit after a downgrade; remaining is never negative.",
+ "properties": {
+ "limit": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "nextCapacityAt": {
+ "anyOf": [
+ {
+ "$ref": "#/$defs/IntegrationTimestamp"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "notice": {
+ "enum": [
+ "approaching_limit",
+ "limit_reached",
+ null
+ ]
+ },
+ "noticeId": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "null"
+ }
+ ]
+ },
+ "period": {
+ "enum": [
+ "day",
+ "week",
+ "month"
+ ]
+ },
+ "remaining": {
+ "minimum": 0,
+ "type": "integer"
+ },
+ "used": {
+ "minimum": 0,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "period",
+ "used",
+ "limit",
+ "remaining",
+ "nextCapacityAt",
+ "notice",
+ "noticeId"
+ ],
+ "type": "object"
+ }
+ },
+ "additionalProperties": false,
+ "properties": {
+ "data": {
+ "additionalProperties": false,
+ "properties": {
+ "connection": {
+ "additionalProperties": false,
+ "description": "This connection's permissions and expiry. An MCP (OAuth) connection stays connected while used: it expires after idleDays without use, at most one year after it was approved. A reconnect from the same app replaces it without using another connection.",
+ "properties": {
+ "canFollow": {
+ "description": "Whether this connection may follow and unfollow markets (the following:write permission).",
+ "type": "boolean"
+ },
+ "expiresAt": {
+ "$ref": "#/$defs/IntegrationTimestamp"
+ },
+ "howToAllowFollowing": {
+ "description": "Present only when canFollow is false: how the user allows following for this connection.",
+ "type": "string"
+ },
+ "idleDays": {
+ "const": 90
+ },
+ "kind": {
+ "enum": [
+ "oauth",
+ "personal_token"
+ ]
+ },
+ "permissions": {
+ "items": {
+ "enum": [
+ "markets:read",
+ "outlooks:read",
+ "performance:read",
+ "results:read",
+ "usage:read",
+ "following:write"
+ ]
+ },
+ "maxItems": 6,
+ "minItems": 1,
+ "type": "array",
+ "uniqueItems": true
+ },
+ "staysConnectedWhileUsed": {
+ "const": true
+ }
+ },
+ "required": [
+ "kind",
+ "permissions",
+ "expiresAt",
+ "canFollow"
+ ],
+ "type": "object"
+ },
+ "outlookLimits": {
+ "additionalProperties": false,
+ "description": "What one get_outlooks call can return.",
+ "properties": {
+ "marketsPerCall": {
+ "const": 1
+ },
+ "maxDurations": {
+ "const": 6
+ },
+ "maxForecasts": {
+ "const": 72
+ }
+ },
+ "required": [
+ "marketsPerCall",
+ "maxDurations",
+ "maxForecasts"
+ ],
+ "type": "object"
+ },
+ "permittedMarkets": {
+ "items": {
+ "$ref": "#/$defs/IntegrationMarketSlug"
+ },
+ "maxItems": 50,
+ "type": "array"
+ }
+ },
+ "required": [
+ "permittedMarkets",
+ "outlookLimits",
+ "connection"
+ ],
+ "type": "object"
+ },
+ "dataUse": {
+ "description": "Use restriction on every reply: data collection is prohibited; the data may not be collected, saved, stored, exported or compiled, or used to train, retrain, fine-tune or distil any model.",
+ "type": "string"
+ },
+ "following": {
+ "$ref": "#/$defs/IntegrationFollowing"
+ },
+ "notices": {
+ "items": {
+ "$ref": "#/$defs/IntegrationNotice"
+ },
+ "maxItems": 3,
+ "type": "array"
+ },
+ "page": {
+ "$ref": "#/$defs/IntegrationPage"
+ },
+ "usage": {
+ "$ref": "#/$defs/IntegrationUsage"
+ }
+ },
+ "required": [
+ "data",
+ "following",
+ "usage",
+ "notices",
+ "page",
+ "dataUse"
+ ],
+ "type": "object"
+}