Skip to main content
Glama

How To Make Money On Snapchat

calculate_gap

Read-onlyIdempotent

CALCULATION. Use this when you need the exact numeric shortfall, percent complete, and binding constraint for a creator's caller-supplied metrics. Do not use it for the pace to close that gap (calculate_growth_pace) or for a per-requirement pass/fail list (check_eligibility).

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
metricsYesMetrics supplied by the caller (the creator or their agent). We never look metrics up ourselves; Snap offers no public analytics for arbitrary usernames. All fields optional; missing fields produce `unknowns`, never guesses. Data minimization: no age, birthdate, name, or username is accepted; creator age is never stored. Caller metrics are checked for plausibility. spotlight_view_time_hours_28d above view_time_hours_28d returns VALUE_INCONSISTENT. view_time_hours_28d above 28 days × 24 hours × followers × 0.5 is a warning that the figure is unusually high for your follower count, please check for a typo. The warning also says view time can come from non-followers. followers of 0 with hours above 0 is the same kind of warning, never an error.
programNoPrograms the calculation tools evaluate in v1. Other in-scope programs (payouts, tax, snap_star, creator_monetization_policy, recommendation_eligibility, brand_partnerships) are served as FACTs by get_monetization_requirements; Snap Star status is evaluated as a prerequisite inside unified_monetization_program.unified_monetization_program
already_enrolledNoSet true only if the creator is already enrolled in the Monetization Program. Default false: only entry (invitation) requirements are evaluated. When true, ongoing requirements for enrolled creators are reported in a separate section.
include_recommendationsNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
gapsYesEntry requirements only.
toolYes
factsYes
noticeYesNon-affiliation notice included in every response.
programYesProgram identifier. Validated at runtime against programs present in the rules database; unknown values return UNKNOWN_PROGRAM. Examples: unified_monetization_program, snap_star, creator_subscriptions, brand_partnerships, payouts, tax, recommendation_eligibility, creator_monetization_policy, public_profile, lens_creator_rewards.
sourcesYes
unknownsYes
warningsNoPlain strings. Omitted when empty. Calculation tools add a string when followers is 0 and view_time_hours_28d or spotlight_view_time_hours_28d is above 0, and when view_time_hours_28d exceeds 28 days × 24 hours × followers × 0.5. Those warnings say the figure is unusually high for your follower count, please check for a typo, and that view time can come from non-followers. They are never an error. FACT GET aliases append ignored query parameter notices to this same array. Spotlight hours above total view hours are HTTP 400 VALUE_INCONSISTENT rather than a warning.
api_versionYes
generated_atYes
ongoing_gapsYesnull unless already_enrolled=true.
data_freshnessYes
recommendationsYes
already_enrolledYes
binding_constraintYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • changedInput schema / description
      Previous value: -"CALCULATION tool. Exact shortfall for each numeric entry requirement of the Monetization Program: absolute amount and percent complete, and which gap is the binding constraint. Ongoing requirements for enrolled creators are reported separately only when already_enrolled=true."New value: +"CALCULATION tool. Exact shortfall for each numeric entry requirement of the Monetization Program: absolute amount and percent complete, and which gap is the binding constraint. Ongoing requirements for enrolled creators are reported separately only when already_enrolled=true. Caller metrics are checked for plausibility. spotlight_view_time_hours_28d above view_time_hours_28d returns VALUE_INCONSISTENT. view_time_hours_28d above 28 days × 24 hours × followers × 0.5 is a warning that the figure is unusually high for your follower count, please check for a typo. The warning also says view time can come from non-followers. followers of 0 with hours above 0 is the same kind of warning, never an error."
    • changedInput schema / properties / metrics / description
      Previous value: -"Metrics supplied by the caller (the creator or their agent). We never look metrics up ourselves; Snap offers no public analytics for arbitrary usernames. All fields optional; missing fields produce `unknowns`, never guesses. Data minimization: no age, birthdate, name, or username is accepted; creator age is never stored."New value: +"Metrics supplied by the caller (the creator or their agent). We never look metrics up ourselves; Snap offers no public analytics for arbitrary usernames. All fields optional; missing fields produce `unknowns`, never guesses. Data minimization: no age, birthdate, name, or username is accepted; creator age is never stored. Caller metrics are checked for plausibility. spotlight_view_time_hours_28d above view_time_hours_28d returns VALUE_INCONSISTENT. view_time_hours_28d above 28 days × 24 hours × followers × 0.5 is a warning that the figure is unusually high for your follower count, please check for a typo. The warning also says view time can come from non-followers. followers of 0 with hours above 0 is the same kind of warning, never an error."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$id": "https://howtomakemoneyonsnapchat.com/schemas/v1/calculate_gap.output.schema.json",
      +  "$schema": "https://json-schema.org/draft/2020-12/schema",
      +  "additionalProperties": false,
      +  "allOf": [
      +    {
      +      "description": "Fields present in every successful tool output.",
      +      "properties": {
      +        "api_version": {
      +          "const": "v1"
      +        },
      +        "data_freshness": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "generated_at": {
      +              "format": "date-time",
      +              "type": "string"
      +            },
      +            "newest_verified_at": {
      +              "format": "date",
      +              "type": [
      +                "string",
      +                "null"
      +              ]
      +            },
      +            "oldest_verified_at": {
      +              "format": "date",
      +              "type": [
      +                "string",
      +                "null"
      +              ]
      +            },
      +            "policy": {
      +              "description": "Human-readable freshness policy, e.g. 'Sources are re-checked daily; rules not re-verified within 7 days are listed as stale.'",
      +              "type": "string"
      +            },
      +            "rules_db_version": {
      +              "description": "Monotonic version of the published rules set. Pattern YYYY-MM-DD.n",
      +              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}\\.[0-9]+$",
      +              "type": "string"
      +            },
      +            "stale_rule_ids": {
      +              "description": "Rules in this response whose verified_at is older than the staleness window stated in `policy`.",
      +              "items": {
      +                "maxLength": 120,
      +                "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +                "type": "string"
      +              },
      +              "type": "array"
      +            }
      +          },
      +          "required": [
      +            "rules_db_version",
      +            "generated_at",
      +            "oldest_verified_at",
      +            "newest_verified_at",
      +            "stale_rule_ids",
      +            "policy"
      +          ],
      +          "type": "object"
      +        },
      +        "generated_at": {
      +          "format": "date-time",
      +          "type": "string"
      +        },
      +        "notice": {
      +          "const": "HowToMakeMoneyOnSnapchat.com is an independent third party and is not affiliated with, endorsed by, or sponsored by Snap Inc. Snapchat is a trademark of Snap Inc.",
      +          "description": "Non-affiliation notice included in every response.",
      +          "type": "string"
      +        },
      +        "sources": {
      +          "items": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "publisher": {
      +                "type": "string"
      +              },
      +              "supports_rule_ids": {
      +                "items": {
      +                  "maxLength": 120,
      +                  "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              },
      +              "title": {
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "url": {
      +                "format": "uri",
      +                "type": "string"
      +              },
      +              "verified_at": {
      +                "format": "date",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "url",
      +              "publisher",
      +              "verified_at",
      +              "supports_rule_ids"
      +            ],
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "tool": {
      +          "type": "string"
      +        },
      +        "warnings": {
      +          "description": "Plain strings. Omitted when empty. Calculation tools add a string when followers is 0 and view_time_hours_28d or spotlight_view_time_hours_28d is above 0, and when view_time_hours_28d exceeds 28 days × 24 hours × followers × 0.5. Those warnings say the figure is unusually high for your follower count, please check for a typo, and that view time can come from non-followers. They are never an error. FACT GET aliases append ignored query parameter notices to this same array. Spotlight hours above total view hours are HTTP 400 VALUE_INCONSISTENT rather than a warning.",
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "tool",
      +        "api_version",
      +        "notice",
      +        "generated_at",
      +        "sources",
      +        "data_freshness"
      +      ],
      +      "type": "object"
      +    }
      +  ],
      +  "properties": {
      +    "already_enrolled": {
      +      "type": "boolean"
      +    },
      +    "api_version": {
      +      "const": "v1"
      +    },
      +    "binding_constraint": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "metric": {
      +          "enum": [
      +            "followers",
      +            "view_time_hours_28d",
      +            "spotlight_view_time_hours_28d",
      +            "posts_per_month",
      +            "active_posting_days_28d"
      +          ],
      +          "type": "string"
      +        },
      +        "percent_complete": {
      +          "type": "number"
      +        },
      +        "rule": {
      +          "const": "unmet requirement with the lowest percent_complete; ties broken by rule_id"
      +        },
      +        "rule_id": {
      +          "maxLength": 120,
      +          "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "rule_id",
      +        "metric",
      +        "percent_complete",
      +        "rule"
      +      ],
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    },
      +    "data_freshness": {
      +      "additionalProperties": false,
      +      "properties": {
      +        "generated_at": {
      +          "format": "date-time",
      +          "type": "string"
      +        },
      +        "newest_verified_at": {
      +          "format": "date",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "oldest_verified_at": {
      +          "format": "date",
      +          "type": [
      +            "string",
      +            "null"
      +          ]
      +        },
      +        "policy": {
      +          "description": "Human-readable freshness policy, e.g. 'Sources are re-checked daily; rules not re-verified within 7 days are listed as stale.'",
      +          "type": "string"
      +        },
      +        "rules_db_version": {
      +          "description": "Monotonic version of the published rules set. Pattern YYYY-MM-DD.n",
      +          "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}\\.[0-9]+$",
      +          "type": "string"
      +        },
      +        "stale_rule_ids": {
      +          "description": "Rules in this response whose verified_at is older than the staleness window stated in `policy`.",
      +          "items": {
      +            "maxLength": 120,
      +            "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +            "type": "string"
      +          },
      +          "type": "array"
      +        }
      +      },
      +      "required": [
      +        "rules_db_version",
      +        "generated_at",
      +        "oldest_verified_at",
      +        "newest_verified_at",
      +        "stale_rule_ids",
      +        "policy"
      +      ],
      +      "type": "object"
      +    },
      +    "facts": {
      +      "items": {
      +        "additionalProperties": false,
      +        "description": "FACT: a rule record as stored in the versioned rules database (approved records only).",
      +        "properties": {
      +          "applies_to": {
      +            "enum": [
      +              "entry",
      +              "enrolled_creators",
      +              "all",
      +              "not_applicable"
      +            ],
      +            "type": "string"
      +          },
      +          "changed_after": {
      +            "description": "Inclusive start of an observed change window when the source does not state a single effective_date. Null when unknown. Additive.",
      +            "format": "date",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "changed_before": {
      +            "description": "Inclusive end of an observed change window when the source does not state a single effective_date. Null when unknown. Additive.",
      +            "format": "date",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "claim": {
      +            "type": "string"
      +          },
      +          "date_note": {
      +            "description": "How changed_after and changed_before were established. Null when there is no window note. Not a substitute for source_url.",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "effective_date": {
      +            "format": "date",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "effective_date_note": {
      +            "const": "not published by Snap",
      +            "description": "Present when effective_date is null because Snap did not publish a date. effective_date stays null."
      +          },
      +          "iso_countries": {
      +            "description": "ISO 3166-1 codes for each name in a country list, from the reviewed country map. Omitted unless this fact is a country list.",
      +            "items": {
      +              "additionalProperties": false,
      +              "properties": {
      +                "alpha2": {
      +                  "type": "string"
      +                },
      +                "alpha3": {
      +                  "type": "string"
      +                },
      +                "numeric": {
      +                  "type": "string"
      +                },
      +                "snap_name": {
      +                  "type": "string"
      +                }
      +              },
      +              "required": [
      +                "snap_name",
      +                "alpha2",
      +                "alpha3",
      +                "numeric"
      +              ],
      +              "type": "object"
      +            },
      +            "type": "array"
      +          },
      +          "label": {
      +            "const": "FACT"
      +          },
      +          "metric": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "mvp_scope": {
      +            "enum": [
      +              "in_scope",
      +              "out_of_scope"
      +            ],
      +            "type": "string"
      +          },
      +          "notes": {
      +            "type": "string"
      +          },
      +          "operator": {
      +            "enum": [
      +              "gte",
      +              "gt",
      +              "lte",
      +              "lt",
      +              "eq",
      +              "in",
      +              "is_true",
      +              null
      +            ],
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "program": {
      +            "description": "Program identifier. Validated at runtime against programs present in the rules database; unknown values return UNKNOWN_PROGRAM. Examples: unified_monetization_program, snap_star, creator_subscriptions, brand_partnerships, payouts, tax, recommendation_eligibility, creator_monetization_policy, public_profile, lens_creator_rewards.",
      +            "pattern": "^[a-z0-9_]{2,64}$",
      +            "type": "string"
      +          },
      +          "publisher": {
      +            "type": "string"
      +          },
      +          "related_rule_ids": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "requirement_phase": {
      +            "enum": [
      +              "entry",
      +              "ongoing",
      +              "entry_and_ongoing",
      +              "not_applicable"
      +            ],
      +            "type": "string"
      +          },
      +          "requires_user_confirmation": {
      +            "type": "boolean"
      +          },
      +          "rule_id": {
      +            "maxLength": 120,
      +            "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +            "type": "string"
      +          },
      +          "rule_type": {
      +            "description": "Role of the rule, copied from the rules database. Omitted by older clients. Used to group answer pages.",
      +            "enum": [
      +              "eligibility_threshold",
      +              "eligibility_condition",
      +              "ongoing_condition",
      +              "payout_term",
      +              "tax_term",
      +              "content_policy",
      +              "program_fact",
      +              "program_status",
      +              "supplementary_note",
      +              null
      +            ],
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "source_url": {
      +            "format": "uri",
      +            "type": "string"
      +          },
      +          "status": {
      +            "enum": [
      +              "current",
      +              "historical",
      +              "unverified"
      +            ],
      +            "type": "string"
      +          },
      +          "supersedes": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "unit": {
      +            "type": "string"
      +          },
      +          "value": {
      +            "anyOf": [
      +              {
      +                "type": [
      +                  "number",
      +                  "string",
      +                  "boolean",
      +                  "null"
      +                ]
      +              },
      +              {
      +                "items": {
      +                  "type": "string"
      +                },
      +                "type": "array"
      +              }
      +            ]
      +          },
      +          "verified_at": {
      +            "format": "date",
      +            "type": "string"
      +          },
      +          "version": {
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "window_days": {
      +            "type": [
      +              "integer",
      +              "null"
      +            ]
      +          }
      +        },
      +        "required": [
      +          "label",
      +          "rule_id",
      +          "version",
      +          "program",
      +          "claim",
      +          "value",
      +          "unit",
      +          "status",
      +          "source_url",
      +          "publisher",
      +          "verified_at",
      +          "effective_date",
      +          "requires_user_confirmation",
      +          "applies_to",
      +          "requirement_phase",
      +          "mvp_scope",
      +          "notes"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "gaps": {
      +      "description": "Entry requirements only.",
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "current": {
      +            "type": "number"
      +          },
      +          "formula": {
      +            "type": "string"
      +          },
      +          "label": {
      +            "const": "CALCULATION"
      +          },
      +          "met": {
      +            "type": "boolean"
      +          },
      +          "metric": {
      +            "enum": [
      +              "followers",
      +              "view_time_hours_28d",
      +              "spotlight_view_time_hours_28d",
      +              "posts_per_month",
      +              "active_posting_days_28d"
      +            ],
      +            "type": "string"
      +          },
      +          "percent_complete": {
      +            "description": "min(current / threshold, 1) * 100, rounded to 2 dp",
      +            "maximum": 100,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "percent_complete_uncapped": {
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "rule_id": {
      +            "maxLength": 120,
      +            "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +            "type": "string"
      +          },
      +          "rule_version": {
      +            "type": "integer"
      +          },
      +          "shortfall_absolute": {
      +            "description": "max(threshold - current, 0)",
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "surplus_absolute": {
      +            "description": "max(current - threshold, 0)",
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "threshold": {
      +            "type": "number"
      +          },
      +          "unit": {
      +            "type": "string"
      +          },
      +          "window_days": {
      +            "type": [
      +              "integer",
      +              "null"
      +            ]
      +          }
      +        },
      +        "required": [
      +          "label",
      +          "rule_id",
      +          "rule_version",
      +          "metric",
      +          "unit",
      +          "threshold",
      +          "current",
      +          "met",
      +          "shortfall_absolute",
      +          "percent_complete",
      +          "percent_complete_uncapped",
      +          "formula"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "generated_at": {
      +      "format": "date-time",
      +      "type": "string"
      +    },
      +    "notice": {
      +      "const": "HowToMakeMoneyOnSnapchat.com is an independent third party and is not affiliated with, endorsed by, or sponsored by Snap Inc. Snapchat is a trademark of Snap Inc.",
      +      "description": "Non-affiliation notice included in every response.",
      +      "type": "string"
      +    },
      +    "ongoing_gaps": {
      +      "additionalProperties": false,
      +      "description": "null unless already_enrolled=true.",
      +      "properties": {
      +        "gaps": {
      +          "items": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "current": {
      +                "type": "number"
      +              },
      +              "formula": {
      +                "type": "string"
      +              },
      +              "label": {
      +                "const": "CALCULATION"
      +              },
      +              "met": {
      +                "type": "boolean"
      +              },
      +              "metric": {
      +                "enum": [
      +                  "followers",
      +                  "view_time_hours_28d",
      +                  "spotlight_view_time_hours_28d",
      +                  "posts_per_month",
      +                  "active_posting_days_28d"
      +                ],
      +                "type": "string"
      +              },
      +              "percent_complete": {
      +                "description": "min(current / threshold, 1) * 100, rounded to 2 dp",
      +                "maximum": 100,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "percent_complete_uncapped": {
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "rule_id": {
      +                "maxLength": 120,
      +                "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +                "type": "string"
      +              },
      +              "rule_version": {
      +                "type": "integer"
      +              },
      +              "shortfall_absolute": {
      +                "description": "max(threshold - current, 0)",
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "surplus_absolute": {
      +                "description": "max(current - threshold, 0)",
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "threshold": {
      +                "type": "number"
      +              },
      +              "unit": {
      +                "type": "string"
      +              },
      +              "window_days": {
      +                "type": [
      +                  "integer",
      +                  "null"
      +                ]
      +              }
      +            },
      +            "required": [
      +              "label",
      +              "rule_id",
      +              "rule_version",
      +              "metric",
      +              "unit",
      +              "threshold",
      +              "current",
      +              "met",
      +              "shortfall_absolute",
      +              "percent_complete",
      +              "percent_complete_uncapped",
      +              "formula"
      +            ],
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "note": {
      +          "const": "Ongoing requirements apply only to creators already enrolled in the Monetization Program. Snap says the 100-hour Spotlight view-time requirement is needed to qualify for maximum Creator Rewards; Snap does not say that rewards stop below it."
      +        }
      +      },
      +      "required": [
      +        "note",
      +        "gaps"
      +      ],
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    },
      +    "program": {
      +      "description": "Program identifier. Validated at runtime against programs present in the rules database; unknown values return UNKNOWN_PROGRAM. Examples: unified_monetization_program, snap_star, creator_subscriptions, brand_partnerships, payouts, tax, recommendation_eligibility, creator_monetization_policy, public_profile, lens_creator_rewards.",
      +      "pattern": "^[a-z0-9_]{2,64}$",
      +      "type": "string"
      +    },
      +    "recommendations": {
      +      "items": {
      +        "additionalProperties": false,
      +        "description": "RECOMMENDATION: our suggestion, never a Snap rule. Short and structured; the calling agent writes prose.",
      +        "properties": {
      +          "assumptions": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "minItems": 1,
      +            "type": "array"
      +          },
      +          "label": {
      +            "const": "RECOMMENDATION"
      +          },
      +          "linked_rule_id": {
      +            "maxLength": 120,
      +            "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +            "type": "string"
      +          },
      +          "measurable_target": {
      +            "additionalProperties": false,
      +            "properties": {
      +              "by_date": {
      +                "format": "date",
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "metric": {
      +                "description": "Closed vocabulary of creator metrics the engines understand.",
      +                "enum": [
      +                  "followers",
      +                  "view_time_hours_28d",
      +                  "spotlight_view_time_hours_28d",
      +                  "meets_age_requirement",
      +                  "country",
      +                  "is_snap_star",
      +                  "posts_per_month",
      +                  "active_posting_days_28d"
      +                ],
      +                "type": "string"
      +              },
      +              "unit": {
      +                "type": "string"
      +              },
      +              "value": {
      +                "type": "number"
      +              }
      +            },
      +            "required": [
      +              "metric",
      +              "value",
      +              "unit"
      +            ],
      +            "type": "object"
      +          },
      +          "objective": {
      +            "maxLength": 200,
      +            "type": "string"
      +          },
      +          "order": {
      +            "description": "1 = address first (the binding constraint). An ordering, not a score.",
      +            "minimum": 1,
      +            "type": "integer"
      +          },
      +          "realism_note": {
      +            "description": "Plain statement when the math is unrealistic, e.g. 'Required pace is 20x your observed pace.'",
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "reason": {
      +            "maxLength": 300,
      +            "type": "string"
      +          },
      +          "risks": {
      +            "items": {
      +              "type": "string"
      +            },
      +            "type": "array"
      +          }
      +        },
      +        "required": [
      +          "label",
      +          "objective",
      +          "reason",
      +          "linked_rule_id",
      +          "measurable_target",
      +          "assumptions",
      +          "risks"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "sources": {
      +      "items": {
      +        "additionalProperties": false,
      +        "properties": {
      +          "publisher": {
      +            "type": "string"
      +          },
      +          "supports_rule_ids": {
      +            "items": {
      +              "maxLength": 120,
      +              "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +              "type": "string"
      +            },
      +            "type": "array"
      +          },
      +          "title": {
      +            "type": [
      +              "string",
      +              "null"
      +            ]
      +          },
      +          "url": {
      +            "format": "uri",
      +            "type": "string"
      +          },
      +          "verified_at": {
      +            "format": "date",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "url",
      +          "publisher",
      +          "verified_at",
      +          "supports_rule_ids"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "tool": {
      +      "const": "calculate_gap"
      +    },
      +    "unknowns": {
      +      "items": {
      +        "additionalProperties": false,
      +        "description": "A requirement we could not evaluate, with the reason and what would resolve it.",
      +        "properties": {
      +          "how_to_resolve": {
      +            "type": "string"
      +          },
      +          "missing_metric": {
      +            "anyOf": [
      +              {
      +                "description": "Closed vocabulary of creator metrics the engines understand.",
      +                "enum": [
      +                  "followers",
      +                  "view_time_hours_28d",
      +                  "spotlight_view_time_hours_28d",
      +                  "meets_age_requirement",
      +                  "country",
      +                  "is_snap_star",
      +                  "posts_per_month",
      +                  "active_posting_days_28d"
      +                ],
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          "reason": {
      +            "enum": [
      +              "missing_input",
      +              "rule_unverified",
      +              "requires_user_confirmation",
      +              "not_computable_from_metrics",
      +              "rule_value_not_numeric"
      +            ],
      +            "type": "string"
      +          },
      +          "rule_id": {
      +            "maxLength": 120,
      +            "pattern": "^[a-z0-9_]+(\\.[a-z0-9_]+)+$",
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "rule_id",
      +          "reason",
      +          "how_to_resolve"
      +        ],
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "warnings": {
      +      "description": "Plain strings. Omitted when empty. Calculation tools add a string when followers is 0 and view_time_hours_28d or spotlight_view_time_hours_28d is above 0, and when view_time_hours_28d exceeds 28 days × 24 hours × followers × 0.5. Those warnings say the figure is unusually high for your follower count, please check for a typo, and that view time can come from non-followers. They are never an error. FACT GET aliases append ignored query parameter notices to this same array. Spotlight hours above total view hours are HTTP 400 VALUE_INCONSISTENT rather than a warning.",
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "tool",
      +    "api_version",
      +    "notice",
      +    "generated_at",
      +    "sources",
      +    "data_freshness",
      +    "program",
      +    "already_enrolled",
      +    "gaps",
      +    "ongoing_gaps",
      +    "binding_constraint",
      +    "unknowns",
      +    "facts",
      +    "recommendations"
      +  ],
      +  "title": "calculate_gap output",
      +  "type": "object"
      +}
  2. First observed

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, idempotent, non-destructive), and the description adds meaningful behavior: caller metrics are plausibility-checked, VALUE_INCONSISTENT is returned when spotlight time exceeds view time, high view-time warnings, and unknowns are never guessed. It does not describe pagination or output shape, but with an output schema present that is acceptable.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three front-loaded sentences, the scoping and alternative-routing stated first. Some plausibility wording is duplicated verbatim between the description and the schema, which is mild redundancy but keeps the description self-contained.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a calculation tool with an output schema, the description covers the needed surface: what is computed, its input assumptions, error/warning behavior, and data-minimization constraints. Return-value explanation is correctly delegated to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75% and the nested metrics object is well annotated, so the baseline is 3. The description adds semantics beyond the schema: that metrics must be caller-supplied (never looked up), the data-minimization rule, and the already_enrolled gating of ongoing requirements.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (calculate) plus the exact outputs it produces (numeric shortfall, percent complete, binding constraint) and the input domain (creator's caller-supplied metrics). It explicitly names the two sibling tools it is NOT so an agent can disambiguate without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use ('when you need the exact numeric shortfall') and when-not-to-use, routing to calculate_growth_pace for pace to close and check_eligibility for pass/fail lists. The condition selecting each alternative is stated, not inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources