Skip to main content

Confirm a Download

Mark a downloaded parcel as delivered so ECGrid removes it from your inbox and stops re-delivering it on subsequent polls.

Overview

ECGrid uses an explicit confirmation step to provide at-least-once delivery guarantees. When you download a parcel its status changes temporarily, but it is not removed from the inbox until you confirm the download. If your process crashes before confirming, ECGrid will re-deliver the parcel on the next poll — protecting you from silent data loss.

The rule is simple: save the file to durable storage first, then confirm.

Sequence:

  1. Download the parcel and write bytes to disk (see Download a File).
  2. Verify the write succeeded (file exists, correct size, or parsed without error).
  3. Call the confirm endpoint with the parcelId.
  4. ECGrid sets the parcel status to InBoxTransferred and will not re-deliver it.

:::danger Do Not Confirm Before Saving Only confirm after you have durably saved or successfully processed the file. Confirming a parcel you have not yet saved will result in permanent data loss — ECGrid will not re-deliver it. :::


REST

Endpoint: POST /v2/parcels/confirm

Auth: X-API-Key: <key> header

Step 1 — Send the confirm request

POST https://rest.ecgrid.io/v2/parcels/confirm
Content-Type: application/json
X-API-Key: YOUR_API_KEY
{
"parcelId": 98765
}
FieldTypeRequiredDescription
parcelIdinteger (long)YesThe ID of the parcel you have already downloaded and saved.

Step 2 — Verify the response

{
"success": true,
"data": {
"parcelId": 98765,
"status": "InBoxTransferred"
}
}

A success: true response means ECGrid has recorded the confirmation. The parcel will no longer appear in subsequent InBoxReady inbox list responses.

Code Examples

// .NET 10 — confirm a downloaded parcel using IHttpClientFactory
// "ECGrid" named client is registered with base address and X-API-Key header

using System.Net.Http.Json;

public record ConfirmRequest(long ParcelId);

public record ConfirmData(long ParcelId, string Status);

public record ConfirmResponse(bool Success, ConfirmData Data);

public class ECGridDownloadConfirmer
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly ILogger<ECGridDownloadConfirmer> _logger;

public ECGridDownloadConfirmer(
IHttpClientFactory httpClientFactory,
ILogger<ECGridDownloadConfirmer> logger)
{
_httpClientFactory = httpClientFactory;
_logger = logger;
}

/// <summary>
/// Confirms that a parcel has been received. Call this only after the file has been
/// durably saved. Returns true on success; throws on HTTP or API error.
/// </summary>
public async Task<bool> ConfirmAsync(
long parcelId,
CancellationToken cancellationToken = default)
{
var http = _httpClientFactory.CreateClient("ECGrid");

var response = await http.PostAsJsonAsync(
"/v2/parcels/confirm",
new ConfirmRequest(parcelId),
cancellationToken);

response.EnsureSuccessStatusCode();

var result = await response.Content
.ReadFromJsonAsync<ConfirmResponse>(cancellationToken: cancellationToken)
?? throw new InvalidOperationException("Empty response from confirm endpoint.");

if (!result.Success)
{
_logger.LogWarning("Confirm returned success=false for parcelId={ParcelId}", parcelId);
return false;
}

_logger.LogInformation(
"Confirmed parcelId={ParcelId}, new status={Status}",
parcelId, result.Data.Status);

return true;
}
}

Typical usage — save then confirm:

// Download
string savedPath = await downloader.DownloadToFileAsync(parcel.ParcelId, outputDir, ct);

// Only confirm after the file is durably on disk
bool confirmed = await confirmer.ConfirmAsync(parcel.ParcelId, ct);

if (!confirmed)
logger.LogError("Failed to confirm parcelId={Id} — will retry on next poll", parcel.ParcelId);

:::tip Idempotency Calling confirm more than once on the same parcelId is safe — subsequent calls are no-ops and will still return success: true. :::


SOAP

:::caution Established API The SOAP API is in maintenance mode. For new integrations use REST above. :::

Method: ParcelDownloadConfirm(SessionID, ParcelID)bool

Step 1 — Call ParcelDownloadConfirm

var result = await client.ParcelDownloadConfirmAsync(sessionId, parcelId);
bool confirmed = result.ParcelDownloadConfirmResult;

Returns true if the confirmation was recorded, false if it failed (e.g., parcel not found or already confirmed by another session).

Code Examples

// .NET 10 — dotnet-svcutil generated proxy
// Reference: https://os.ecgrid.io/v4.1/prod/ECGridOS.asmx?WSDL

using ECGridOS;

/// <summary>
/// Downloads a parcel, saves it to disk, and confirms delivery.
/// Confirmation is only sent after the file write succeeds.
/// </summary>
public static async Task DownloadAndConfirmAsync(
ECGridOSAPIClient client,
string sessionId,
int parcelId,
string outputDirectory)
{
// Download the file bytes
var downloadResult = await client.ParcelDownloadAsync(sessionId, parcelId);
byte[] fileBytes = downloadResult.ParcelDownloadResult;

// Retrieve filename from parcel info
var infoResult = await client.ParcelInfoAsync(sessionId, parcelId);
string safeFileName = Path.GetFileName(infoResult.ParcelInfoResult.FileName);
string outputPath = Path.Combine(outputDirectory, safeFileName);

// Write to disk — confirm only if this succeeds
await File.WriteAllBytesAsync(outputPath, fileBytes);
Console.WriteLine($"Saved {outputPath} ({fileBytes.Length} bytes)");

// Confirm delivery
var confirmResult = await client.ParcelDownloadConfirmAsync(sessionId, parcelId);
bool confirmed = confirmResult.ParcelDownloadConfirmResult;

if (confirmed)
Console.WriteLine($"Confirmed parcelId={parcelId}");
else
Console.Error.WriteLine($"WARNING: confirmation failed for parcelId={parcelId}");
}

Why Confirmation Matters

ScenarioWithout ConfirmWith Confirm
Normal operationParcel re-appears on every pollParcel removed from inbox after first successful download
Process crash after downloadFile may be lost with no re-deliveryRe-delivered on next poll — no data loss
Network error during confirm callParcel re-delivered on next pollRe-delivered — idempotent, safe to process again
Double-confirm (retry safe)N/ASecond confirm is a no-op