A successful deployment and a healthy overseas uptime check do not establish that users in mainland China can always connect. A new domain needs an initial observation, and DNS, HTTP and TLS connectivity can change after launch. The purpose of automated GFW checks is not to attach a permanent “not blocked” label to a website. It is to notice changes and give the responsible team a target, a network and a failure stage to investigate.
If you have not used WeaveBit before, start with a Free DNS Pollution Check to understand the public results and their limits. Use Console or the authenticated API for recurring, bulk or programmatic checks; do not automate the free web form or its human verification. This guide focuses on integration with your own operations system. For the first manual check, read the GFW testing introduction.
When should a live website trigger an automated check?
Separate event-driven checks from scheduled checks. An event might be a new domain going live, a completed deployment or an operator requesting a recheck. Associating observations with a release identifier helps compare conditions around a change. Scheduled checks run after launch to help identify anomalies that arise outside deployment windows.
One check triggered by a deployment does not become continuous monitoring. Console or your own scheduler must arrange subsequent runs. A successful deployment script also does not mean its asynchronous checks have finished. If you use observations as a release gate, define when to stop a release, how long to wait and when to request human review. An indeterminate result must not silently become a pass.
Choose Console alerts or an API integration
| Requirement | Suitable route | Who schedules checks and delivers notifications? |
|---|---|---|
| Configure recurring checks and contacts without maintaining a monitoring program | Console monitoring tasks | Use the platform’s task and notification settings, as available in the current interface |
| Associate checks with releases, retain your own history and integrate an existing on-call system | API v2 detection batches | Your application owns triggering, querying, persistence, alert policy and notification delivery |
Creating an API batch only submits that batch. It does not create a recurring Console task or automatically send Console alerts. Follow Getting started if you want the platform to handle scheduling and notifications. If you choose the API route, deploy the scheduling and notification workflow in your own system.
Define domains, methods and a budget first
Inventory domains by business purpose: the main website, login, API and essential resources. For example, a service might use www.example.com, login.example.com and api.example.com. These are illustrative names, not customer evidence. Checking only the main domain cannot establish that login and API dependencies work. Nor should every recurring run include unrelated targets simply to appear comprehensive.
Use dns_pollution_check when you need to observe DNS pollution; omit nodes for that method. Use gfw_full_domain_check to observe DNS pollution, HTTP Host and TLS SNI together, selecting currently available nodes relevant to your users’ regions and carriers. “Full” refers to those three dimensions, not all seven methods or a complete browser page load.
Frequency, target count and node coverage all affect cost and scope. Group domains by business importance, but do not treat an example schedule as a universal recommendation. Obtain nodes with /task/get_nodes, then review /task/estimate using the actual planned request. Use the estimate and available balance returned at that time. Keep domains, methods, ports and nodes consistent when comparing successive observations, and record configuration changes separately.
Make each detection round recoverable
- Record the round before submitting it. Store the business job identifier, trigger and configuration. Generate and persist an
Idempotency-Keyfor this logical creation. A new scheduled round gets a new identity; a retry of this creation keeps the original identity and request body. - Estimate, review and create. Check cost and balance before calling
/task/create, which can incur charges. If a network timeout leaves acceptance uncertain, do not blindly submit again with a different identity. - Persist the batch before querying. Save the returned
batch_id, then call/task/result. After a process restart, resume the existing batch instead of purchasing a replacement round. - Bound polling and read every page. Use limited polling and backoff for
pendingorrunning. When a script’s waiting budget is exhausted, retain state and resume later. Do not loop forever or create more batches to hurry an existing one. - Save observations before applying alert policy. A batch marked
completedhas finished its lifecycle, but may still contain indeterminate results. Preserve results, classifications and timestamps by target and node before deciding whether to notify or investigate.
Querying does not create another check, and poll count is not anomaly count. Reading one batch ten times still represents one round. If your policy confirms an anomaly across several consecutive rounds, count independently completed rounds and avoid consuming the same batch twice.
Distinguish execution_deadline_at from expires_at: one is the execution deadline and the other is result expiry. Under the current public contract, execution can last up to six hours; targets and results expire twenty-four hours after creation, not twenty-four hours after completion. Save required data before the returned expiry. See the API reference for parameters and errors, and the batch detection tutorial for the request workflow.
Separate anomalies, insufficient evidence and API failures
For DNS pollution, read the public result_code. For GFW Full checks, read overall_result within each node’s result, then inspect the component results when investigating. HTTP success, API code=0, batch completion and a normal detection result describe different things.
| Observation | Possible caller-side action | What not to do |
|---|---|---|
Explicit anomaly, classified as 1 | Record the target, node and components; emit an anomaly event under your confirmation policy and recheck when appropriate | Declare that every network in China is affected, or attribute the cause to a particular party from one observation |
Indeterminate, represented by null, or an expected observation is missing | Keep the insufficient-evidence state and arrange a recheck or human review | Turn it into normal, or clear a previous anomaly as recovered |
| An API request or the monitoring program fails | Report a monitoring-pipeline fault separately; inspect authentication, balance, rate limits or scheduling | Call the target blocked, or silently ignore repeated execution failures |
| A previously anomalous target produces interpretable normal results under the same configuration | Apply your recovery policy and retain the original incident record | Declare recovery merely because no new alert arrived |
Confirmation counts, reminder intervals and recovery conditions are your operational policies, not platform defaults prescribed by this article. Track state by target, method and node or an explicit coverage set. A normal result from one region must not overwrite an anomaly from another. If you aggregate events at domain level, retain counts of anomalous, normal, indeterminate and missing observations.
Notification delivery has its own failure states. Generating an event does not establish that an email or Telegram message arrived. When integrating your notification service, retain pending events, confirm delivery and retry failures. Associate reminders and recovery events with the same incident record. See Understanding results for the interpretation boundaries.
Python example: connect checks, persistence and a notification adapter
The Python example below is a teaching reference, not a hosted alerting service or a replacement for the official SDK. Its default dry-run makes no network requests and performs no real detection. Only an explicit --live option, together with your own server-side credentials, enables authenticated API requests. Live creation can incur charges. Never put an API key in a web page, repository, log or notification body.
The example retains the current request and batch in a state file to avoid blind creation after a restart. It writes events as JSON to standard output for a notification adapter to consume. JSON output does not mean an email, Telegram message or other notification has been sent. Connect your own delivery adapter, or use Console monitoring for platform notifications. Do not treat a demonstration state file as a production multi-process queue.
This minimal example treats the entire configured target list as one alerting unit: any explicit anomaly produces an anomaly event, and recovery requires normal observations across the corresponding scope. It retains raw target and node results for investigation, but does not implement a complete per-domain or per-node incident system. If the actual node coverage changes, it retains the previous alarm and flags the change for review rather than clearing the old incident with normal results from a different scope.
Download the Python teaching example and usage notes (ZIP). The configuration file describes targets and nodes. Keep --state in private storage that is not web-accessible, and set a per-round decimal budget with --max-cost. This budget is a caller-side safeguard, not a fixed price; review the actual estimate before running a live check.
This is a core workflow excerpt, not a standalone program. The download includes its helper functions, configuration, offline tests and full instructions. The amount is an example caller-side budget, not a service price.
# Workflow excerpt; download gfw_monitor.py for the complete runnable example.
# run() and the helpers below are defined in that file, not in the SDK.
body = validated_config(config)
with exclusive_state(state_directory):
event = run(body, state_directory, Api(server_side_key), Decimal("0.10"))
print(canonical(event))
# The caller's notification bridge must deliver and retry messages.
# An emitted JSON event is NOT a Telegram/email delivery receipt.
After extracting the archive, first inspect the request plan with a command that makes no network requests:
python3 gfw_monitor.py --config monitor-config.json --state ./private-monitor-state --max-cost 0.10
The supplied configuration demonstrates DNS pollution checks. For GFW Full checks, change the method and current node selection as described in the package. Add --live only after reviewing targets, costs, private state storage and server-side credentials. Your release pipeline or scheduler can invoke the same command to start or resume a round; this article does not enable a schedule for you.
Completed-round events remain in local result files. If standard output or the notification bridge fails, use --replay-events as described in the package to replay them offline. Your bridge should acknowledge delivery using the stable event_id and retry unacknowledged events instead of creating another detection batch.
Read the example’s arguments and limitations before running it. In a test environment, check recovery after an uncertain create response, complete pagination, indeterminate results, anomaly-to-recovery transitions and notification failures. For reusable clients, see the official lightweight SDKs and code examples. Alert policy and business-state persistence remain your application’s responsibility.
Check these boundaries before production use
- Cost: deduplicate targets, use a relevant node set, review estimates before creation and monitor available balance. Creation retries must not become duplicate paid rounds.
- Execution: prevent overlapping runs for the same business job and resume unfinished batches. Use reliable locks, a database and queues for multi-process operation rather than sharing the demonstration file.
- Retries: set connection and request timeouts, a total waiting budget and bounded backoff. Respect
Retry-Afterwhen rate-limited. If results or idempotency retention have expired, reconcile business state before treating another create as a safe retry. - Alerts: test target anomalies, indeterminate observations, monitoring-program faults and delivery failures independently. Confirm that the responsible person receives messages, not just that a script exits successfully.
- Evidence: retain times, targets, nodes, ports, components and rechecks. Investigate alongside origin logs, CDN information and user reports. Protocol checks do not replace browser-level business validation.
You do not need a complex monitoring system to begin. Use a Free DNS Pollution Check to understand the result first. Then choose the workflow your team can maintain: Console for platform notifications, or the authenticated API to integrate GFW checks into existing operations.