Singapore Bunker Demand & Tanker Flow Divergence avatar

Singapore Bunker Demand & Tanker Flow Divergence

Pricing

from $0.0425 / delivered singapore divergence report

Go to Apify Store
Singapore Bunker Demand & Tanker Flow Divergence

Singapore Bunker Demand & Tanker Flow Divergence

Compare official monthly Singapore bunker demand, tanker arrivals, fuel mix, and vessel calls in one evidence report. Add optional bounded BYOK tanker pressure, with publication lag, freshness, confidence, null reasons, provenance, gaps, and human review.

Pricing

from $0.0425 / delivered singapore divergence report

Rating

0.0

(0)

Developer

Tim Zinin

Tim Zinin

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

2 days ago

Last modified

Share

Singapore Bunker and Tanker Divergence: official evidence, direction, confidence, and review

Singapore Bunker and Tanker Divergence: two bounded signals to one reviewable report

What this Actor does

This Actor measures whether Singapore's official monthly bunker demand and tanker arrivals are moving together or apart. It combines four Singapore Government data.gov.sg resources covering tanker arrivals and gross tonnage, total bunker sales, bunker sales by fuel type, and vessel calls.

The official data is monthly and may lag publication. The report exposes latestMonth and lagMonths; it does not describe official data as real-time. Optional open_plus_byok mode adds aggregate live tanker pressure from two bounded Datalastic provider requests: /stat plus a fixed 10 NM Singapore zone, accepting up to 500 rows. It does not sell or return raw AIS data.

Key features

  • Aggregate tanker arrivals, gross tonnage, bunker demand, low-carbon share, and vessel calls.
  • Exact 3-month and 12-month baselines only when the required prior months are consecutive and category-complete.
  • Explicit null reasons for unavailable baselines, month-over-month values, and year-over-year values.
  • Same-watch locking before any buyer-funded Datalastic request.
  • One confirmed result-found delivery at most, with state saved while the lock is still owned and confirmed billing never rewritten as unknown.
  • Aggregate-only output with no MMSI, IMO, vessel names, coordinates, routes, provider keys, or identity salt.

Input

schemaVersion is required; requestId, watchId, and sourceMode default to auto, singapore-bunker-main, and open respectively. sourceMode is:

  • demo: synthetic fixture, one Dataset row after the $0.005 actor-start charge, and no $0.05 result-found event;
  • open: four official Singapore datasets without a provider key;
  • open_plus_byok: requires a syntactically valid buyer-owned Datalastic key before any official source, lock, provider call, pricing check, or delivery; then uses the official datasets plus /stat and one fixed Singapore-zone request.

baselineMonths defaults to 12. maxRows defaults to 240 and is bounded to 240–500. Each official resource uses one page; four first attempts are expected, while retries share one Actor-wide budget of 12 actual HTTP attempts. Older history is marked partialReason: older_history_truncated and is accepted only after exact required-field, numeric, cardinality, uniqueness, and latest-plus-baseline validation. The observed monthly cardinalities are 8 arrival categories, 1 bunker-total row, 16 bunker-breakdown categories, and 5 vessel-call categories. Vessel-call validation uses the published call count; the source's nullable gross-tonnage column is not requested or used by this product. maxProviderRequests is fixed at 2 for BYOK. maxTotalChargeUsd defaults to $0.055.

How to run

Use the Actor input editor or an Apify Task with requestId: "auto". An open-mode input is:

{
"schemaVersion": "1.0",
"requestId": "auto",
"watchId": "singapore-bunker-main",
"sourceMode": "open",
"baselineMonths": 12,
"maxRows": 240,
"maxProviderRequests": 2,
"maxTotalChargeUsd": 0.055
}

For open_plus_byok, add a buyer-owned datalasticApiKey. Omit the field for demo and open; an explicit null is invalid in every mode. The key is secret input and is used in memory to derive the live identity salt; neither value is output or persisted. If a request or watch identifier contains the current key, the run fails before source, lock, billing, or state effects and only a domain-separated opaque identifier may appear in the terminal envelope.

Output

Every useful run delivers one aggregate report. official.coverage states whether the requested consecutive baseline and monthly-lag policy are satisfied and records the expected monthly category cardinalities. A representative terminal envelope is:

{
"schemaVersion": "1.0",
"actor": "singapore-bunker-tanker-divergence",
"requestId": "run-id",
"status": "complete",
"resultFound": true,
"billedResultCount": 1,
"baselineAdvanced": true,
"report": {
"status": "complete",
"official": {
"latestMonth": "2026-05",
"lagMonths": 1,
"complete": true,
"coverage": {
"complete": true,
"reason": null,
"requiredPriorMonths": 12,
"consecutivePriorMonths": 12
}
}
},
"errors": []
}

Replay safety is fail-closed. A persisted request intent is treated as untrusted data and must match the closed Actor/schema/request/watch/report/state contract; malformed, poisoned, PREPARED, or AMBIGUOUS replays return request_replay_blocked with no report and do not call Datalastic, charge, or write state. An UNCHARGED replay returns the same budget refusal with zero billing and no effects. A clean confirmed replay does not charge again and may only save a state validated against the current input contract.

Persisted report sources, licenses, attribution URLs, limitations, signal names, and absence reasons are canonical enum codes. reportId is recomputed from the complete unsigned report, including the exact previousStateDigest, and replay runs through the same semantic validator as newly generated reports. A complete report is bootstrap only with an empty predecessor and complete only with a valid predecessor digest; partial reports remain partial. Every sources[].retrievedAt timestamp must be no later than observedAt; no positive clock skew is accepted, and complete live freshness is checked by exact timestamp arithmetic. Every nullable decision value has an exact paired reason: null requires a reason and a present value requires a null reason. The closed ledger stores the exact predecessor state and digest plus a null-only delivery receipt field, binds source mode and state-contract/final-state digests, and rejects provider prose, raw identities, and credentials before OUTPUT, Dataset, KVS, or logs. A definitive second-gate budget refusal is persisted as UNCHARGED and replays as the same zero-billing result; only uncertain delivery remains AMBIGUOUS. Confirmed reconciliation authenticates the recorded predecessor-to-next-state transition before accepting an identical or monotonic successor, then remains monotonic under the watch lock with prefix lineage before 365 observations and ring-buffer overlap lineage at the cap, so an older replay cannot overwrite a newer baseline.

If any source lacks the required complete consecutive months, has a malformed/duplicate/negative row, exhausts the shared attempt budget, returns an unclassified partial response, or is more than three calendar months behind the run month, no useful paid report is delivered. baseline12Month and yearOverYearPercent remain null with explicit reasons. State is saved after exact paid-delivery confirmation while the same-watch lock is still held, then the lock is released. A state-write failure reports resultFound: true, billedResultCount: 1, and baselineAdvanced: false. Release uncertainty after a proven save reports resultFound: true, billedResultCount: 1, and baselineAdvanced: true; it never erases known billing or state proof.

Pricing

The exact base PPE contract is $0.005 for apify-actor-start and $0.05 for one delivered result-found report, for $0.055 total before buyer-owned provider costs. Allowed discount tiers are 0%, 5%, 10%, 15%, 18%, and 20%. There is no priced default Dataset-item event. Demo mode still incurs the actor-start charge but has no $0.05 result fee.

Data quality

Completeness requires the latest common category-complete month plus baselineMonths prior consecutive complete months across every promised series. The latest official month may lag the run month by at most three calendar months; month three is eligible and is not labelled stale, while month four and beyond are partial, emit DATA_STALE, and fail closed without a result event. A partial edge month, a missing middle month, or truncated multi-category response is excluded rather than silently aggregated. Live pressure requires an exact complete response for the fixed 10 NM Singapore zone, at least one safe tanker snapshot, and at least 95% fresh coverage. Structurally valid snapshots older than 3600 seconds are excluded and reflected in provider/accepted counts; malformed, future, empty, or lower-coverage responses fail closed.

Singapore Government attribution: Singapore Open Data Licence. Datalastic data is used only for derived aggregates under provider terms.

Limitations

  • Official records are monthly and may be published with a delay.
  • The Actor is not for navigation and does not claim official berth, queue, booking-slot, or real-time vessel status.
  • The fixed 12-request official ceiling can still be insufficient if source cardinality increases; that run fails closed.
  • Live pressure is not a route, identity, sanctions, ownership, or tactical signal.
  • Source outages, incomplete coverage, budget caps, state failures, lock failures, and uncertain billing fail closed.

What the Actor gives you

The product answers a bounded question: are official Singapore bunker-demand measures and tanker-flow measures moving together, or is there a reviewable divergence? It creates one aggregate evidence report with the current official period, prior-period comparisons, baseline availability, optional live pressure, quality limitations, and deterministic signals.

It is useful for commercial analysts, bunker-market teams, maritime research, capacity review, and evidence collection when the decision owner needs a compact record rather than raw source tables. The report can help a reviewer decide whether to investigate timing, product mix, inventory behavior, vessel-call composition, or publication lag.

It does not prove causality. A divergence can be caused by window alignment, reporting definitions, fuel mix, vessel class, cargo timing, storage behavior, source revisions, or incomplete live coverage. The Actor does not choose between those explanations and does not trade, route, book, notify, or write to another system.

Official evidence included

Open mode reads four fixed Singapore Government resources through bounded, schema-checked requests. The public report carries the publisher, exact Dataset identifier, retrieval timestamp, licence code, and attribution URL.

Evidence familyReport useCompleteness rule
Vessel arrivalsTanker arrivals and gross tonnage by month.Exact expected categories, unique rows, numeric nonnegative measures, consecutive months.
Total bunker salesCurrent demand, month-over-month and year-over-year comparison.Exactly one eligible total per month, required offset months present.
Bunker sales by fuel typeProduct composition and low-carbon share.Exact expected fuel categories with no duplicate or malformed records.
Vessel callsWider port-activity context.Published call-count field only; nullable source gross tonnage is intentionally not used.

The official source is monthly. latestMonth is the latest category-complete month common to every required series. lagMonths is calendar lag from the run month. A lag of three remains eligible; four or more is partial and cannot create a paid useful report. This is a publication-lag rule, not a claim about the age of every underlying commercial activity.

The Actor requests only the columns used in its contract. It does not fill missing months, interpolate absent categories, replace null values with zero, or silently accept a partial edge month. Those choices are deliberate: a missing middle month can change a trend conclusion even when the latest value looks valid.

Optional live pressure

open_plus_byok adds a second evidence family: aggregate safe tanker snapshots inside one fixed 10 NM Singapore zone. It performs one provider-account check and one bounded zone request. The provider key remains buyer-controlled, and the output excludes vessel identities, coordinates, routes, names, source prose, and the key.

Live pressure is eligible only when:

  • the provider response is explicitly complete and contains no error or partial marker;
  • at least one safe tanker snapshot is accepted;
  • every accepted identity and position needed internally is structurally valid;
  • source timestamps are not in the future and no accepted snapshot is older than one hour;
  • fresh timestamp coverage is at least 95%; and
  • provider and accepted counts reconcile with the stated coverage.

Older but structurally valid rows are excluded and counted in the coverage evidence. Malformed, future, empty, or below-threshold coverage fails closed. A live count is a bounded observed pressure measure; it is not a complete port queue, berth schedule, route, or official vessel-call count.

How to read the report

Read the report in this order:

  1. status tells you whether the report is bootstrap, complete, or partial.
  2. dataQuality states confidence, source completeness, official publication month, lag, and partial state.
  3. official.coverage shows whether all consecutive months and category cardinalities were present.
  4. official metrics give the current values and exact baseline comparisons.
  5. live shows optional bounded tanker pressure and its independent freshness/coverage evidence.
  6. signals lists thresholds that were actually crossed.
  7. limitations, reason fields, and sources state what is missing and where the evidence came from.

Null is evidence, not zero

Every nullable decision metric has a paired reason. A 12-month baseline may be null because twelve consecutive complete prior months do not exist. A live ratio may be null because live mode was not requested, the source was incomplete, or too few safe observations were available. Downstream code should preserve both the null and its reason; coercing null to zero creates a conclusion the source did not support.

Signals are review triggers

Signals use fixed thresholds. Bunker-demand changes are emitted at plus or minus five percent. A tanker-arrival surge requires a current-to-three-month-baseline ratio of at least 1.2. A low-carbon-share increase requires at least one percentage point. Boundary tests intentionally exclude 0.99 percentage points.

A signal is not a forecast, recommendation, or proof of cause. It means a deterministic threshold over complete accepted inputs was met. No signal means the threshold was not met, not that the market is normal.

Evidence-to-action workflow

Use the Actor as one step in a reviewed process:

  1. Define the watch and the commercial question before seeing the result.
  2. Confirm official coverage and publication lag.
  3. Separate monthly official movement from optional short-lived tanker pressure.
  4. Inspect product mix and source definitions before comparing magnitudes.
  5. Review every null reason and partial limitation.
  6. Record plausible explanations as hypotheses, not facts.
  7. Decide whether to investigate, annotate, monitor, or close the review.
  8. Store the reportId, observation month, source list, build/run identifiers, and reviewer outcome.

Examples of sensible next actions include checking whether a changed fuel mix explains a total, waiting for a revised month, comparing with a separate price series, or asking an authorized provider for greater coverage. Examples of unsafe actions include automatically trading, changing voyage instructions, identifying a vessel, or claiming a causal supply disruption from one divergence report.

Delivery, billing, and replay truth

The Dataset is the report channel; OUTPUT is the authoritative run and settlement channel. A useful non-demo report is delivered with one linked result-found event. Demo uses an ordinary unpriced Dataset write and still incurs the automatic start event.

OutcomeDatasetResult eventStateRetry guidance
DemoOne synthetic reportZeroNot advancedA fresh run is a fresh start purchase.
Confirmed useful reportOne aggregate reportExactly oneAdvanced after confirmed deliveryDo not rerun to “confirm” billing.
Definitive budget refusalNo useful paid reportConfirmed zeroNot advancedSame request replays the refusal without new effects.
Source or quality refusalDiagnostic OUTPUT onlyNot attemptedNot advancedCorrect the evidence problem before a new request.
Ambiguous deliveryMay already contain a rowUnknownNot advancedNever retry blindly; reconcile the existing run.
State save failurePaid report remains confirmedExactly onePersistence unknown/not advancedInvestigate state; do not buy the same evidence again.
Lock release uncertaintyPreserves proven row and billingPreserves known countPreserves proven saveInvestigate lock ownership before scheduling again.

The request-intent ledger provides replay control for the same derived request. It does not make an unrelated new run free. Each new Actor run still incurs the automatic start event, and a genuinely new useful observation can emit a new paid result.

API, Tasks, schedules, and MCP

For a one-off open-data report:

curl -X POST \
"https://api.apify.com/v2/acts/zinin~singapore-bunker-tanker-divergence/runs?token=$APIFY_TOKEN" \
-H "content-type: application/json" \
-d '{
"schemaVersion":"1.0",
"requestId":"auto",
"watchId":"singapore-bunker-main",
"sourceMode":"open",
"baselineMonths":12,
"maxRows":240,
"maxProviderRequests":2,
"maxTotalChargeUsd":0.055
}'

For a schedule, create a Task with a stable watchId. Use requestId: "auto" unless you are deliberately reconciling one known request. Do not overlap runs for the same watch. A same-watch lock protects the baseline, but avoiding overlap also keeps schedules, reviews, and billing easier to reason about.

An MCP or automation client should wait for the platform terminal status, then read OUTPUT, the Dataset, and charged-event counts. Accept a useful result only when the output/report schemas pass, the Dataset report matches OUTPUT.report, the report digest is valid, the quality contract is complete, and the platform shows the expected start plus exactly one result event.

The Actor never calls a CRM, sends an alert, changes a booking, or executes a trade. Those actions require a separate reviewed automation with its own authorization and failure handling.

Rights, attribution, privacy, and retention

Singapore Government records are used under the Singapore Open Data Licence and retain source attribution in the report. Follow the linked licence for attribution, permitted use, disclaimers, and change indication. The Actor transforms source tables into aggregate comparisons; it does not represent the output as an official Singapore Government conclusion.

Datalastic mode is BYOK. You are responsible for a provider plan and permissions that cover collection, transformation, retention, and downstream use. Public output is aggregate-only, but salted or hashed source identities remain pseudonymous technical data rather than a universal guarantee of legal anonymity.

Use a documented business purpose, restrict access, and set retention for Actor Datasets, KVS records, Tasks, exports, and downstream copies. Do not submit secrets in identifiers or URLs. Do not combine the report with other data to identify vessels, owners, crews, cargo, sanctions status, military activity, or individual behavior.

Production checklist

Before enabling a recurring watch:

  • run demo to verify your integration without a result event;
  • run open to verify official-source access and attribution;
  • use open_plus_byok only after provider-rights and key handling are approved;
  • keep a stable, non-secret watchId and an explicit owner for the review;
  • ensure the charge cap covers the current tier's start plus one result;
  • preserve nulls and reason fields in downstream storage;
  • alert on partial, ambiguous, state-write, and lock-release states without automatic retry;
  • retain run/build/report identifiers and platform event counts for reconciliation;
  • define storage retention and deletion before scheduling.

Troubleshooting

SymptomMeaningResponse
older_history_truncatedRows outside the bounded useful history were present.Verify the required current and consecutive baseline months remain complete.
DATA_STALEOfficial lag exceeds three months or another quality gate failed.Inspect latestMonth, lagMonths, coverage, and source errors.
Null 12-month metricThe exact offset or consecutive category-complete history is absent.Preserve the reason; do not substitute zero or a shorter baseline.
Live pressure unavailableBYOK was not requested or live coverage failed.Inspect provider/accepted counts, timestamps, and coverage reason.
watch_busyAnother run owns the same watch.Wait for it to settle; do not start a retry race.
request_replay_blockedStored intent/state is prepared, ambiguous, poisoned, or incompatible.Reconcile the original run and storage before creating new work.
Budget refusalCap cannot cover current tier settlement.Review the price tier and cap; the result unit remains uncharged.

Acceptance criteria

A production consumer should classify a run as accepted only when the exact build is known, the platform run succeeded, OUTPUT is present and schema-valid, the Dataset contains the expected one aggregate report, the Dataset row and OUTPUT.report are identical, reportId recomputes, official coverage is complete, lag is within policy, required live coverage is complete when requested, no partial condition is present, and platform event counts reconcile to one start and one new result unit. A demo is accepted under a different rule: one synthetic Dataset row, zero result units, and no state advance.

FAQ

Why is a 12-month baseline null?

At least 12 prior consecutive category-complete months are required. The reason field identifies missing or truncated coverage.

Is demo completely free?

No. Demo has no $0.05 result-found fee, but the $0.005 actor-start charge still applies at the base tier.

Does a busy watch spend Datalastic calls?

No. The same-watch lock is acquired before /stat or the Singapore-zone request.

ActorWorkflow reason
Strait of Hormuz Tanker Flow RecoveryCompare Singapore bunker demand with aggregate tanker-flow recovery through Hormuz.
Panama Canal Queue Transit ImbalanceCompare Singapore demand pressure with aggregate canal-side transit imbalance.
Live Price OracleAdd current market-price context to a bunker-demand change.
Counterparty Risk RollupApply a separate buyer-owned risk review to downstream counterparties.

Built by zinin.