Singapore Bunker Demand & Tanker Flow Divergence
Pricing
from $0.0425 / delivered singapore divergence report
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
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share


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-founddelivery 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.005actor-start charge, and no$0.05result-foundevent;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/statand 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 family | Report use | Completeness rule |
|---|---|---|
| Vessel arrivals | Tanker arrivals and gross tonnage by month. | Exact expected categories, unique rows, numeric nonnegative measures, consecutive months. |
| Total bunker sales | Current demand, month-over-month and year-over-year comparison. | Exactly one eligible total per month, required offset months present. |
| Bunker sales by fuel type | Product composition and low-carbon share. | Exact expected fuel categories with no duplicate or malformed records. |
| Vessel calls | Wider 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:
statustells you whether the report isbootstrap,complete, orpartial.dataQualitystates confidence, source completeness, official publication month, lag, and partial state.official.coverageshows whether all consecutive months and category cardinalities were present.officialmetrics give the current values and exact baseline comparisons.liveshows optional bounded tanker pressure and its independent freshness/coverage evidence.signalslists thresholds that were actually crossed.limitations, reason fields, andsourcesstate 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:
- Define the watch and the commercial question before seeing the result.
- Confirm official coverage and publication lag.
- Separate monthly official movement from optional short-lived tanker pressure.
- Inspect product mix and source definitions before comparing magnitudes.
- Review every null reason and partial limitation.
- Record plausible explanations as hypotheses, not facts.
- Decide whether to investigate, annotate, monitor, or close the review.
- 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.
| Outcome | Dataset | Result event | State | Retry guidance |
|---|---|---|---|---|
| Demo | One synthetic report | Zero | Not advanced | A fresh run is a fresh start purchase. |
| Confirmed useful report | One aggregate report | Exactly one | Advanced after confirmed delivery | Do not rerun to “confirm” billing. |
| Definitive budget refusal | No useful paid report | Confirmed zero | Not advanced | Same request replays the refusal without new effects. |
| Source or quality refusal | Diagnostic OUTPUT only | Not attempted | Not advanced | Correct the evidence problem before a new request. |
| Ambiguous delivery | May already contain a row | Unknown | Not advanced | Never retry blindly; reconcile the existing run. |
| State save failure | Paid report remains confirmed | Exactly one | Persistence unknown/not advanced | Investigate state; do not buy the same evidence again. |
| Lock release uncertainty | Preserves proven row and billing | Preserves known count | Preserves proven save | Investigate 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
demoto verify your integration without a result event; - run
opento verify official-source access and attribution; - use
open_plus_byokonly after provider-rights and key handling are approved; - keep a stable, non-secret
watchIdand 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
| Symptom | Meaning | Response |
|---|---|---|
older_history_truncated | Rows outside the bounded useful history were present. | Verify the required current and consecutive baseline months remain complete. |
DATA_STALE | Official lag exceeds three months or another quality gate failed. | Inspect latestMonth, lagMonths, coverage, and source errors. |
| Null 12-month metric | The exact offset or consecutive category-complete history is absent. | Preserve the reason; do not substitute zero or a shorter baseline. |
| Live pressure unavailable | BYOK was not requested or live coverage failed. | Inspect provider/accepted counts, timestamps, and coverage reason. |
watch_busy | Another run owns the same watch. | Wait for it to settle; do not start a retry race. |
request_replay_blocked | Stored intent/state is prepared, ambiguous, poisoned, or incompatible. | Reconcile the original run and storage before creating new work. |
| Budget refusal | Cap 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.
Related Actors
| Actor | Workflow reason |
|---|---|
| Strait of Hormuz Tanker Flow Recovery | Compare Singapore bunker demand with aggregate tanker-flow recovery through Hormuz. |
| Panama Canal Queue Transit Imbalance | Compare Singapore demand pressure with aggregate canal-side transit imbalance. |
| Live Price Oracle | Add current market-price context to a bunker-demand change. |
| Counterparty Risk Rollup | Apply a separate buyer-owned risk review to downstream counterparties. |
Built by zinin.