Create a read-only view link for a sheet
#!/usr/bin/env bashset -euo pipefailAPI=https://api.speccapture.comAUTH="Authorization: Bearer $SPECCAPTURE_API_KEY"
JOB_ID=7c9e6679-7425-40de-944b-e07fc1f90ae7 # the jobId the submission answered withSHEET_NUMBER=1 # which sheet: 1 is the first page
link=$(curl -sS --fail-with-body "$API/v1/extractions/$JOB_ID/sheets/$SHEET_NUMBER/view-links" \ -H "$AUTH" \ -H "Content-Type: application/json" \ -d '{"expiresInDays":30}') || { echo "$link" >&2; exit 1; }jq -r '"Anyone with this link sees the sheet until \(.expiresAt): \(.viewUrl)"' <<<"$link"jq -r '"To withdraw it: \(.viewLinkId)"' <<<"$link"using System.Text;using System.Text.Json;using System.Text.Json.Nodes;
using HttpClient http = new() { BaseAddress = new Uri("https://api.speccapture.com") };http.DefaultRequestHeaders.Authorization = new("Bearer", Environment.GetEnvironmentVariable("SPECCAPTURE_API_KEY"));
string jobId = args[0]; // the jobId the submission answered withstring sheetNumber = args[1]; // which sheet: 1 is the first page
StringContent body = new(new JsonObject { ["expiresInDays"] = 30 }.ToJsonString(), Encoding.UTF8, "application/json");JsonElement link = await Json(await Call(HttpMethod.Post, $"/v1/extractions/{jobId}/sheets/{sheetNumber}/view-links", body));Console.WriteLine($"Anyone with this link sees the sheet until {link.GetProperty("expiresAt")}: {link.GetProperty("viewUrl")}");Console.WriteLine($"To withdraw it: {link.GetProperty("viewLinkId")}");
// Sends a request; stops with the problem's code and detail if the API refuses it.async Task<HttpResponseMessage> Call(HttpMethod method, string path, HttpContent? body = null, string? idempotencyKey = null) { using HttpRequestMessage request = new(method, path) { Content = body }; if (idempotencyKey is not null) request.Headers.Add("Idempotency-Key", idempotencyKey); HttpResponseMessage response = await http.SendAsync(request); if (!response.IsSuccessStatusCode) { JsonElement problem = await Json(response); string? detail = (problem.TryGetProperty("detail", out JsonElement text) ? text : problem.GetProperty("title")).GetString(); Console.Error.WriteLine($"{(int)response.StatusCode} {problem.GetProperty("code")}: {detail}"); Environment.Exit(1); } return response;}
// Reads an answer as JSON.static async Task<JsonElement> Json(HttpResponseMessage response) => JsonDocument.Parse(await response.Content.ReadAsStringAsync()).RootElement;import osimport sys
import requests
API = "https://api.speccapture.com"session = requests.Session()session.headers["Authorization"] = f"Bearer {os.environ['SPECCAPTURE_API_KEY']}"
def call(method, path, **kwargs): """Send a request; stop with the problem's code and detail if the API refuses it.""" response = session.request(method, API + path, **kwargs) if not response.ok: problem = response.json() sys.exit(f"{response.status_code} {problem['code']}: {problem.get('detail', problem['title'])}") return response
job_id = sys.argv[1] # the jobId the submission answered withsheet_number = sys.argv[2] # which sheet: 1 is the first page
link = call( "POST", f"/v1/extractions/{job_id}/sheets/{sheet_number}/view-links", json={"expiresInDays": 30},).json()print(f"Anyone with this link sees the sheet until {link['expiresAt']}: {link['viewUrl']}")print(f"To withdraw it: {link['viewLinkId']}")const API = "https://api.speccapture.com";const headers = { Authorization: `Bearer ${process.env.SPECCAPTURE_API_KEY}` };
const [jobId, sheetNumber] = process.argv.slice(2); // the jobId the submission answered with; which sheet: 1 is the first page
const link = await call("POST", `/v1/extractions/${jobId}/sheets/${sheetNumber}/view-links`, { body: JSON.stringify({ expiresInDays: 30 }), headers: { "Content-Type": "application/json" },}).then((response) => response.json());console.log(`Anyone with this link sees the sheet until ${link.expiresAt}: ${link.viewUrl}`);console.log(`To withdraw it: ${link.viewLinkId}`);
// Sends a request; stops with the problem's code and detail if the API refuses it.async function call(method, path, init = {}) { const response = await fetch(API + path, { ...init, method, headers: { ...headers, ...init.headers } }); if (!response.ok) { const problem = await response.json(); console.error(`${response.status} ${problem.code}: ${problem.detail ?? problem.title}`); process.exit(1); } return response;}Answers 201 with viewUrl: the sheet’s drawing with every value’s box and confidence, for anyone holding the link, with no sign-in, until expiresAt or until it is withdrawn. Shown once; results never carry it. Body (optional): { “expiresInDays”: 1-90 }, 30 by default, capped by the workspace’s retention. Add ?field=
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Request Body
Section titled “Request Body”Responses
Section titled “Responses”Created
object
Bad Request: a problem with a stable code. See Errors for every code and what to do about it.
Every error: a problem with a stable code. https://speccapture.com/docs/api/errors lists every code.
object
A link to the code’s entry in the docs.
What went wrong, as a stable code to branch on: a published code never changes meaning.
This request’s trace: quote it when asking for help.
Forbidden: a problem with a stable code. See Errors for every code and what to do about it.
Every error: a problem with a stable code. https://speccapture.com/docs/api/errors lists every code.
object
A link to the code’s entry in the docs.
What went wrong, as a stable code to branch on: a published code never changes meaning.
This request’s trace: quote it when asking for help.
Not Found: a problem with a stable code. See Errors for every code and what to do about it.
Every error: a problem with a stable code. https://speccapture.com/docs/api/errors lists every code.
object
A link to the code’s entry in the docs.
What went wrong, as a stable code to branch on: a published code never changes meaning.
This request’s trace: quote it when asking for help.
Conflict: a problem with a stable code. See Errors for every code and what to do about it.
Every error: a problem with a stable code. https://speccapture.com/docs/api/errors lists every code.
object
A link to the code’s entry in the docs.
What went wrong, as a stable code to branch on: a published code never changes meaning.
This request’s trace: quote it when asking for help.