Skip to content
    OpenMoney
    LedgerMethodologySchemaSourcesDocs
    Sign inStart your Passport

    Version 1.0.0

    Open Opportunity Schema

    The open, evidence-first schema behind every registry record. Published as JSON Schema (draft 2020-12), a JSON-LD context mapped to schema.org, and the @openmoney/schema package with Zod validators.

    Machine-readable files

    • provider.schema.json
    • opportunity.schema.json
    • risk-flag.schema.json
    • scorecard.schema.json
    • evidence.schema.json
    • source.schema.json
    • context.jsonld

    Canonical base: https://openmoney.ai/schema/v1/

    Provider

    The platform or company: identity, domains, jurisdictions, verification state, published policies.

    Provider fields
    FieldTypeRequiredDescription
    idstringrequiredRegistry id, e.g. "freelancer-com".
    legalNamestringrequiredRegistered legal name of the operating entity.
    brandNamestringrequiredName earners know the platform by.
    domainstringrequiredCanonical registrable domain, e.g. "freelancer.com".
    otherDomainsstring[]requiredOther domains the provider operates (regional sites, help centers).
    hqobjectrequiredWhere the provider is headquartered.
    hq.countrystring | nullrequiredHeadquarters country; null when unknown.
    hq.regionstring | nullrequiredState, province, or city of the headquarters; null when unknown.
    jurisdictionsstring[]requiredCountries whose law governs earner terms.
    categories"rideshare" | "delivery" | "local_shifts" | "home_services" | "care" | "freelance" | "ai_training" | "microtask" | "research" | "selling" | "leasing" | "tutoring" | "creator" | "agent_bounty" | "open_source" | "other"[]requiredRegistry categories.
    entityVerificationobjectrequiredWhether the operating legal entity is real and matches the brand.
    entityVerification.status"verified" | "unverified" | "suspicious"requiredVerification outcome.
    entityVerification.methodstring | nullrequiredHow the legal entity was checked, e.g. "company register lookup", "WHOIS + terms page".
    entityVerification.verifiedAtstring (date-time) | nullrequiredWhen the check was performed; null if never.
    entityVerification.evidenceIdsstring[]requiredSources supporting the verification status.
    paymentVerificationobjectrequiredWhether the provider has been observed actually paying earners.
    paymentVerification.status"verified" | "unverified" | "suspicious"requiredVerification outcome.
    paymentVerification.methodstring | nullrequiredHow payment was verified, e.g. "observed payout to a Passport holder", "payment processor disclosure".
    paymentVerification.verifiedAtstring (date-time) | nullrequiredWhen payment was last verified; null if never.
    termsUrlstring (uri) | nullrequiredPublished terms of service for earners; null if none found.
    payoutPolicyUrlstring (uri) | nullrequiredPublished payout or fees policy; null if none found.
    deactivationPolicyUrlstring (uri) | nullrequiredPublished deactivation or account-termination policy; null if none found.
    appealsProcessobjectrequiredDeactivation appeals: whether earners can appeal and whether a human reviews it.
    appealsProcess.existsboolean | nullrequiredWhether a published appeals process exists; null when unknown.
    appealsProcess.humanReviewboolean | nullrequiredWhether a human reviews appeals; null when unknown.
    appealsProcess.evidenceIdsstring[]requiredSources supporting the answers.
    fairworkScoresobject[]requiredFairwork ratings by country and year.
    fairworkScores[].countrystringrequiredISO 3166-1 alpha-2 country code, e.g. US, IN.
    fairworkScores[].yearintegerrequiredRating year.
    fairworkScores[].scoreintegerrequiredFairwork score out of 10.
    fairworkScores[].urlstring (uri)requiredFairwork ratings page for that country and year.
    sourcesobject[]requiredEvery source cited by this record.
    sources[].idstringrequiredSource id, referenced by sourceId / sourceIds / evidenceIds elsewhere in the record.
    sources[].urlstring (uri)requiredExact URL of the page or dataset.
    sources[].publisherstringrequiredWho published it (organisation name).
    sources[].titlestringoptionalPage or document title.
    sources[].type"platform_disclosure" | "regulatory_filing" | "third_party_dataset" | "survey" | "passport_aggregate" | "user_report" | "internal_measurement"requiredKind of source: platform_disclosure, regulatory_filing, third_party_dataset, survey, passport_aggregate, user_report, internal_measurement.
    sources[].retrievedAtstring (date-time)requiredWhen we fetched it (ISO 8601 date-time).
    sources[].checksumstringoptionalSHA-256 hex of the retrieved body, when known.
    sources[].reachability"unchecked" | "ok" | "redirected" | "unreachable" | "changed"optionalLast link-check result: unchecked, ok, redirected, unreachable, changed.
    sources[].lastCheckedAtstring (date-time)optionalWhen the link was last checked.
    sources[].publishedAtstring (date)optionalPublication or period date stated by the source itself.
    sources[].notesstringoptionalCurator notes, typically the verbatim sentences the figures were read from.
    version"1.0.0"requiredOpen Opportunity Schema version.
    updatedAtstring (date-time)requiredWhen this record was last edited.

    Opportunity

    One way to earn on a provider: eligibility, pay evidence as distributions, fee schedule, payout terms, stability, risk flags.

    Opportunity fields
    FieldTypeRequiredDescription
    idstringrequiredRegistry id, e.g. "freelancer-com:projects".
    providerIdstringrequiredId of the Provider offering this opportunity.
    kind"platform_gig" | "freelance_marketplace" | "ai_training" | "local_shift" | "selling" | "leasing" | "research_study" | "agent_bounty" | "employer_posting" | "open_source_bounty"requiredWhat kind of earning this is.
    titlestringrequiredShort name, sentence case.
    descriptionstringrequiredWhat the work is, in plain words.
    workMode"remote" | "onsite" | "hybrid"requiredWhere the work happens.
    geoobjectrequiredGeographic availability.
    geo.countriesstring[]requiredCountries where the opportunity is offered. Empty means worldwide or unknown; see eligibility.
    geo.regionsstring[]requiredStates, provinces, or regions, when limited.
    geo.citiesstring[]requiredCities or metros, when limited.
    eligibilityobjectrequiredWho can do this work.
    eligibility.minAgeinteger | nullrequiredMinimum age; null when not stated.
    eligibility.vehicle"none" | "bicycle" | "scooter" | "car" | "van" | "truck" | "any" | nullrequiredVehicle required; null when not stated.
    eligibility.equipmentstring[]requiredEquipment the earner must supply, e.g. "smartphone", "insulated bag".
    eligibility.credentialsstring[]requiredLicenses, certifications, or degrees required.
    eligibility.backgroundCheckboolean | nullrequiredWhether a background check is required; null when not stated.
    eligibility.countriesstring[]requiredCountries of residence accepted, when they differ from geo.countries.
    payEvidenceobject[]requiredPay distributions with sources. Empty until evidence exists; never estimated.
    payEvidence[].metric"net_hourly" | "gross_hourly" | "per_task" | "per_project"requiredWhat the pay figures measure.
    payEvidence[].currencystringrequiredISO 4217 currency code, e.g. USD, INR.
    payEvidence[].p25integer | nullrequired25th percentile in minor units; null when not reported.
    payEvidence[].p50integer | nullrequiredMedian in minor units; null when not reported.
    payEvidence[].p90integer | nullrequired90th percentile in minor units; null when not reported.
    payEvidence[].ninteger | nullrequiredSample size; null when the source does not state one.
    payEvidence[].periodStartstring (date)requiredFirst day of the period the figures cover.
    payEvidence[].periodEndstring (date)requiredLast day of the period the figures cover.
    payEvidence[].sourceType"passport_aggregate" | "platform_disclosure" | "third_party_dataset" | "survey" | "regulatory_filing"requiredWhere a pay figure comes from.
    payEvidence[].sourceIdstringrequiredId of a source in the enclosing record's `sources[]`. Every number carries one.
    feeScheduleobject[]requiredPublished fees, each with a source.
    feeSchedule[].namestringrequiredFee name as the provider states it.
    feeSchedule[].type"percent" | "fixed" | "per_application" | "subscription" | "withdrawal" | "instant_pay"requiredFee category.
    feeSchedule[].valueintegerrequiredFee amount: basis points when unit is basis_points, minor units of `currency` when unit is minor_units.
    feeSchedule[].unit"basis_points" | "minor_units"requiredHow `value` is expressed: basis points of the base, or minor units of `currency`.
    feeSchedule[].currencystringoptionalRequired when unit is minor_units.
    feeSchedule[].minimumobjectoptionalFloor applied to a percent fee ("10% or $5, whichever is greater").
    feeSchedule[].minimum.amountMinorintegeroptionalAmount in minor units (cents, paise). Integer; never a float.
    feeSchedule[].minimum.currencystringoptionalISO 4217 currency code, e.g. USD, INR.
    feeSchedule[].appliesTostringrequiredWhat the fee applies to, e.g. "fixed-price project earnings", "each withdrawal via PayPal".
    feeSchedule[].sourceIdstringrequiredId of a source in the enclosing record's `sources[]`. Every number carries one.
    payoutTermsobject | nullrequiredPayout terms; null when not yet documented.
    onboardingCostobject | nullrequiredOnboarding cost; null when not yet documented.
    stabilityobjectrequiredHow dependable the work and the account are.
    stability.taskAvailabilitySignal"high" | "medium" | "low" | "unknown"requiredWhether there is usually work available.
    stability.observedDeactivationRateinteger | nullrequiredShare of earners deactivated per year, in basis points; null when unknown.
    stability.reportedUnpaidWorkIncidentsinteger | nullrequiredCount of reported unpaid-work incidents in the period; null when unknown.
    stability.sourceIdsstring[]requiredSources for the stability figures.
    riskFlagsobject[]requiredScam and reliability signals, each with evidence.
    riskFlags[].code"UPFRONT_FEE" | "TASK_SCAM_PATTERN" | "CRYPTO_ONLY_PAYOUT" | "OFF_PLATFORM_ONLY_MESSAGING" | "CHECK_DEPOSIT_SCHEME" | "EQUIPMENT_PURCHASE_REQUIRED" | "DOMAIN_AGE_UNDER_90D" | "DOMAIN_MISMATCH" | "UNSUBSTANTIATED_EARNINGS_CLAIM" | "MLM_STRUCTURE" | "GHOST_POSTING" | "BRAND_IMPERSONATION" | "UNPAID_WORK_REPORTS" | "NO_APPEALS_PROCESS"requiredScam-signature rule code.
    riskFlags[].severity"info" | "low" | "medium" | "high" | "critical"requiredHow serious the signal is.
    riskFlags[].evidenceobjectrequiredThe evidence a flag rests on. A flag cannot exist without it.
    riskFlags[].evidence.sourceIdstringrequiredId of a source in the enclosing record's `sources[]`. Every number carries one.
    riskFlags[].evidence.quotestringoptionalVerbatim excerpt from the source that triggered the flag.
    riskFlags[].evidence.observedAtstring (date-time)requiredWhen the evidence was observed.
    riskFlags[].detectedBy"rule" | "curator" | "report"requiredWho or what raised the flag.
    riskFlags[].ruleVersionstringrequiredVersion of the rule set or curator guideline that raised the flag, e.g. "scam-rules@1.0.0".
    agentPostablebooleanrequiredWhether AI agents may post or apply on behalf of a principal.
    postedByobjectrequiredWho posted this and, for agents, whose Proof backs them.
    postedBy.type"provider" | "agent" | "employer"requiredWho posted the opportunity.
    postedBy.agentIdstringoptionalAgent id when posted by an agent.
    postedBy.principalProofIdstringoptionalProof id of the agent's human principal when posted by an agent.
    lastVerifiedAtstring (date-time)requiredWhen a curator last confirmed the record against its sources.
    scorecardobject | nullrequiredScorecard; null before the first computation.
    sourcesobject[]requiredEvery source cited by this record.
    sources[].idstringrequiredSource id, referenced by sourceId / sourceIds / evidenceIds elsewhere in the record.
    sources[].urlstring (uri)requiredExact URL of the page or dataset.
    sources[].publisherstringrequiredWho published it (organisation name).
    sources[].titlestringoptionalPage or document title.
    sources[].type"platform_disclosure" | "regulatory_filing" | "third_party_dataset" | "survey" | "passport_aggregate" | "user_report" | "internal_measurement"requiredKind of source: platform_disclosure, regulatory_filing, third_party_dataset, survey, passport_aggregate, user_report, internal_measurement.
    sources[].retrievedAtstring (date-time)requiredWhen we fetched it (ISO 8601 date-time).
    sources[].checksumstringoptionalSHA-256 hex of the retrieved body, when known.
    sources[].reachability"unchecked" | "ok" | "redirected" | "unreachable" | "changed"optionalLast link-check result: unchecked, ok, redirected, unreachable, changed.
    sources[].lastCheckedAtstring (date-time)optionalWhen the link was last checked.
    sources[].publishedAtstring (date)optionalPublication or period date stated by the source itself.
    sources[].notesstringoptionalCurator notes, typically the verbatim sentences the figures were read from.
    version"1.0.0"requiredOpen Opportunity Schema version.

    RiskFlag

    A scam-signature code with severity and the evidence it fired on. A flag cannot exist without evidence.

    RiskFlag fields
    FieldTypeRequiredDescription
    code"UPFRONT_FEE" | "TASK_SCAM_PATTERN" | "CRYPTO_ONLY_PAYOUT" | "OFF_PLATFORM_ONLY_MESSAGING" | "CHECK_DEPOSIT_SCHEME" | "EQUIPMENT_PURCHASE_REQUIRED" | "DOMAIN_AGE_UNDER_90D" | "DOMAIN_MISMATCH" | "UNSUBSTANTIATED_EARNINGS_CLAIM" | "MLM_STRUCTURE" | "GHOST_POSTING" | "BRAND_IMPERSONATION" | "UNPAID_WORK_REPORTS" | "NO_APPEALS_PROCESS"requiredScam-signature rule code.
    severity"info" | "low" | "medium" | "high" | "critical"requiredHow serious the signal is.
    evidenceobjectrequiredThe evidence a flag rests on. A flag cannot exist without it.
    evidence.sourceIdstringrequiredId of a source in the enclosing record's `sources[]`. Every number carries one.
    evidence.quotestringoptionalVerbatim excerpt from the source that triggered the flag.
    evidence.observedAtstring (date-time)requiredWhen the evidence was observed.
    detectedBy"rule" | "curator" | "report"requiredWho or what raised the flag.
    ruleVersionstringrequiredVersion of the rule set or curator guideline that raised the flag, e.g. "scam-rules@1.0.0".

    Scorecard

    Six dimensions with confidence, a composite that is marked partial when evidence is missing, and the methodology version.

    Scorecard fields
    FieldTypeRequiredDescription
    payobjectrequiredPay: median net hourly vs. local minimum wage and category median.
    pay.scoreinteger | nullrequired0–100, or null when there is insufficient evidence.
    pay.confidence"high" | "medium" | "low" | "insufficient"requiredConfidence in the score: high, medium, low, or insufficient.
    pay.evidenceIdsstring[]requiredSources the score was computed from.
    feesobjectrequiredFees: total extraction rate including unpaid onboarding.
    fees.scoreinteger | nullrequired0–100, or null when there is insufficient evidence.
    fees.confidence"high" | "medium" | "low" | "insufficient"requiredConfidence in the score: high, medium, low, or insufficient.
    fees.evidenceIdsstring[]requiredSources the score was computed from.
    payoutobjectrequiredPayout: frequency, delay, minimum, reliability incidents.
    payout.scoreinteger | nullrequired0–100, or null when there is insufficient evidence.
    payout.confidence"high" | "medium" | "low" | "insufficient"requiredConfidence in the score: high, medium, low, or insufficient.
    payout.evidenceIdsstring[]requiredSources the score was computed from.
    stabilityobjectrequiredStability: task availability, deactivation rate, unpaid-work incidents, appeals.
    stability.scoreinteger | nullrequired0–100, or null when there is insufficient evidence.
    stability.confidence"high" | "medium" | "low" | "insufficient"requiredConfidence in the score: high, medium, low, or insufficient.
    stability.evidenceIdsstring[]requiredSources the score was computed from.
    transparencyobjectrequiredTransparency: published terms, fees, deactivation policy, pay disclosures.
    transparency.scoreinteger | nullrequired0–100, or null when there is insufficient evidence.
    transparency.confidence"high" | "medium" | "low" | "insufficient"requiredConfidence in the score: high, medium, low, or insufficient.
    transparency.evidenceIdsstring[]requiredSources the score was computed from.
    scamRiskobjectrequiredScam risk (inverted: 100 = no signals): risk flags, verification, domain age, complaints.
    scamRisk.scoreinteger | nullrequired0–100, or null when there is insufficient evidence.
    scamRisk.confidence"high" | "medium" | "low" | "insufficient"requiredConfidence in the score: high, medium, low, or insufficient.
    scamRisk.evidenceIdsstring[]requiredSources the score was computed from.
    compositeobjectrequiredThe weighted composite and how it was computed.
    composite.scoreinteger | nullrequiredWeighted composite 0–100, or null when no dimension has evidence.
    composite.partialbooleanrequiredTrue when at least one dimension was excluded for insufficient evidence.
    composite.weightsobjectrequiredComposite weights per dimension in basis points; they sum to 10000.
    composite.weights.payintegerrequiredPercentage in basis points (10000 = 100%).
    composite.weights.feesintegerrequiredPercentage in basis points (10000 = 100%).
    composite.weights.payoutintegerrequiredPercentage in basis points (10000 = 100%).
    composite.weights.stabilityintegerrequiredPercentage in basis points (10000 = 100%).
    composite.weights.transparencyintegerrequiredPercentage in basis points (10000 = 100%).
    composite.weights.scamRiskintegerrequiredPercentage in basis points (10000 = 100%).
    composite.methodologyVersionstringrequiredVersion of the scoring methodology that produced this composite, e.g. "scoring@1.0.0".
    computedAtstring (date-time)requiredWhen the scorecard was computed.
    MethodologySchemaSourcesDocsTransparencyPrivacyTermsAccessibility

    © 2026 All Things AI, Inc.. Neutral by construction: no affiliate links, no paid placement, no earnings claims.