{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://opengrants.io/common-grants/schemas/state-portal-v1.json",
  "title": "OpenGrants state portal custom fields (v1)",
  "description": "The customFields an OpenGrants state grants portal adds to a CommonGrants v0.5.0 OpportunityBase. Fields that exist in the CommonGrants custom-field catalog (costSharing, contactInfo, eligibilityCriteria, additionalInfo) are emitted with the catalog's own value shapes and `schema` pointing at the catalog, not here. The keys below are the portal's shared, uncataloged fields, defined identically for every state portal OpenGrants publishes; each entry is a CommonGrants CustomField whose `schema` points at this document. The vocabulary covers what a state program page states that OpportunityBase has no field for (applicant types, funding source and method, geography, how to apply, the application cycle in words) plus the state identifiers (statutory authority, state catalog number) a state needs to adopt the record set.",
  "type": "object",
  "properties": {
    "fundingInstrument": {
      "type": "string",
      "enum": [
        "grant",
        "loan",
        "grant+loan",
        "tax credit",
        "rebate",
        "in-kind",
        "other"
      ],
      "description": "Shared with the CA/PA/MD/WA reference implementations; the kind of money"
    },
    "lastSyncedAt": {
      "type": "string",
      "format": "date-time",
      "description": "When the OpenGrants record data behind this opportunity was last refreshed (UTC)"
    },
    "stateCode": {
      "type": "string",
      "pattern": "^[A-Z]{2}$",
      "description": "USPS code of the state whose agency offers the funding"
    },
    "agencyKey": {
      "type": "string",
      "pattern": "^[a-z0-9]+(?:-[a-z0-9]+)*$",
      "description": "Portal key of the administering agency (agencies.json)"
    },
    "agencyAbbrev": {
      "type": "string",
      "description": "Administering agency abbreviation"
    },
    "agencyUrl": {
      "type": "string",
      "format": "uri",
      "description": "Administering agency website"
    },
    "categories": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Portal categories (the portal config's list; one or more per record)"
    },
    "applicantTypes": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "Public Agency",
          "Nonprofit",
          "Tribal Government",
          "Business",
          "Individual",
          "School District",
          "Higher Education",
          "Other Legal Entity"
        ]
      }
    },
    "applicantTypesNotes": {
      "type": "string"
    },
    "purpose": {
      "type": "string"
    },
    "geography": {
      "type": "string",
      "description": "Geographic limits within the state, free text as the funder states them"
    },
    "fundingSource": {
      "type": "string",
      "enum": [
        "State",
        "Federal",
        "Federal and State",
        "Other"
      ]
    },
    "fundingSourceNotes": {
      "type": "string"
    },
    "matchingFunds": {
      "type": "string",
      "description": "\"Not Required\" or a percentage such as \"25%\""
    },
    "fundingMethod": {
      "type": "string",
      "enum": [
        "Reimbursement(s)",
        "Advance(s)",
        "Advances & Reimbursement(s)",
        "Other"
      ]
    },
    "fundingMethodNotes": {
      "type": "string"
    },
    "loiRequired": {
      "type": "boolean"
    },
    "estimatedAwards": {
      "type": "string",
      "description": "As published, e.g. \"Between 1 and 10\""
    },
    "estimatedAmounts": {
      "type": "string",
      "description": "As published, e.g. \"Between $850,000 and $1,250,000\""
    },
    "estimatedAvailableFunds": {
      "type": "string"
    },
    "awardPeriod": {
      "type": "string"
    },
    "howToApply": {
      "type": "string"
    },
    "electronicSubmission": {
      "type": "string",
      "description": "Where applications are submitted: url: <application portal>; or email: <address>"
    },
    "statutoryAuthority": {
      "type": "string",
      "description": "Statute or rule that authorizes the program, e.g. \"s. 376.80, F.S.\""
    },
    "stateCatalogNumber": {
      "type": "string",
      "description": "The program's number in the state's catalog of financial assistance (Florida CSFA, Illinois CSFA, etc.)"
    },
    "cycle": {
      "type": "string",
      "description": "Application cycle pattern in words"
    },
    "nextDeadlineDisplay": {
      "type": "string"
    },
    "deadlineSource": {
      "type": "string",
      "enum": [
        "editorial",
        "record",
        "cycle",
        "record-live"
      ]
    },
    "stringsAttached": {
      "type": "string"
    },
    "applicantTip": {
      "type": "string"
    },
    "programSlug": {
      "type": "string",
      "description": "Stable program slug within the portal; the v5 opportunity id is derived from it"
    },
    "programUrl": {
      "type": "string",
      "format": "uri"
    },
    "opengrantsListingUrl": {
      "type": "string",
      "format": "uri"
    },
    "bindingMode": {
      "type": "string",
      "enum": [
        "record",
        "upstream",
        "pending-import",
        "none",
        "portfolio"
      ]
    },
    "upstreamSource": {
      "type": "string",
      "description": "Id of the upstream CommonGrants API this record is read from or also served by; its record id is in identifiers.otherIds[\"opp:<upstreamSource>:system\"]"
    },
    "upstreamConformance": {
      "type": "array",
      "items": { "type": "string" },
      "description": "What the upstream record failed of CommonGrants v0.5.0 before the portal served it"
    },
    "verifiedOn": {
      "type": "string",
      "format": "date"
    },
    "cardStatus": {
      "type": "string",
      "enum": [
        "published",
        "needs_review",
        "retired"
      ]
    },
    "portfolioSlug": {
      "type": "string"
    }
  },
  "additionalProperties": false
}
