api2convert 10.2.0 → 10.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +1 -1
  3. data/README.md +43 -0
  4. data/docs/CHANGELOG.md +4 -2
  5. data/docs/SDK_CONTRACT.md +57 -6
  6. data/examples/add_watermark.rb +36 -0
  7. data/examples/audio_operations.rb +21 -0
  8. data/examples/authentication.rb +13 -0
  9. data/examples/capture_website.rb +29 -0
  10. data/examples/compare_files.rb +34 -0
  11. data/examples/compress_files.rb +18 -0
  12. data/examples/convert_files.rb +24 -0
  13. data/examples/create_archives.rb +29 -0
  14. data/examples/create_hashes.rb +19 -0
  15. data/examples/create_thumbnails.rb +22 -0
  16. data/examples/extract_assets.rb +16 -0
  17. data/examples/file_analysis.rb +17 -0
  18. data/examples/image_operations.rb +21 -0
  19. data/examples/job_lifecycle.rb +29 -0
  20. data/examples/presets.rb +14 -0
  21. data/examples/quickstart.rb +22 -0
  22. data/examples/rate_limits.rb +12 -0
  23. data/examples/statistics.rb +12 -0
  24. data/examples/uploading_files.rb +27 -0
  25. data/examples/webhooks.rb +24 -0
  26. data/lib/api2convert/client.rb +29 -5
  27. data/lib/api2convert/cloud_provider.rb +29 -0
  28. data/lib/api2convert/http/net_http_sender.rb +31 -3
  29. data/lib/api2convert/http/request.rb +7 -5
  30. data/lib/api2convert/http/transport.rb +18 -3
  31. data/lib/api2convert/model/cloud_input.rb +108 -0
  32. data/lib/api2convert/model/conversion.rb +7 -3
  33. data/lib/api2convert/model/input_file.rb +8 -3
  34. data/lib/api2convert/model/output_target.rb +78 -0
  35. data/lib/api2convert/resource/jobs.rb +6 -2
  36. data/lib/api2convert/resource/stats.rb +2 -1
  37. data/lib/api2convert/result.rb +51 -20
  38. data/lib/api2convert/support/data.rb +8 -1
  39. data/lib/api2convert/support/redactor.rb +83 -0
  40. data/lib/api2convert/upload/file_uploader.rb +2 -2
  41. data/lib/api2convert/version.rb +1 -1
  42. data/lib/api2convert.rb +4 -0
  43. data/openapi/api2convert.openapi.json +51 -51
  44. metadata +26 -3
  45. data/examples/convert.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3d6b5c540037362377c06e4096518c623017c17882b39233f932f73f0b70d14
4
- data.tar.gz: 37b28638fbef0fd35e3eff63abb8557fd27c4400a4c4e63bab170dbf86d0fd8e
3
+ metadata.gz: ab0c201184fae5e154e8eb8dda08b1dd523f6721b8c0ea63882f36b0d08d69a8
4
+ data.tar.gz: 51d41801caf9b731b48b2f988b2f76605638b455b90a337c4ce6ce2acbfda4d6
5
5
  SHA512:
6
- metadata.gz: 83f600ae36bd429c61df404004a744b2cb51dad8aedab4c739c79ed83b8c95d77542c5162d0c356a84cb7515d369457f6264c92c1d03c898a84c74768148444c
7
- data.tar.gz: 63031c428a7bb3ea8e976ac2861c38dc27b83585ab41c0927ad24660a3c1d9a2aee10724b6b9b743ea947019e026f941ab84272fefb472b88a0fbd5710c3a4e0
6
+ metadata.gz: e1a07542793b7fe4f016907ba28b6e25bc6d887bf0549714b3233350994f561534604a79f1488df8c69efc7cd40f76340a73486938fa5c82fb9424a8f63417d6
7
+ data.tar.gz: bd3a8cdc13f9d5092a54f91d7e6ef3caa5e7627b2bee607e8203afda5a7991d5356749ce35da48afcd0ae8420e3e43cf6b52f359b37bdfc6feba030111fefb24
data/AGENTS.md CHANGED
@@ -63,7 +63,7 @@ junior-friendly surface — one-call `convert` — and use AI to keep it current
63
63
  key/token in errors. Secret-scan before any release.
64
64
  - **The contract is law.** Public method names, signatures and semantics match `docs/SDK_CONTRACT.md`
65
65
  across every SDK language. Adapt only to Ruby idiom (see divergences below).
66
- - **Upload uses the per-job `X-Oc-Token`, never the account key.** There is a spec for this.
66
+ - **Upload uses the per-job `X-Api2convert-Token`, never the account key.** There is a spec for this.
67
67
  - **Secret-bearing requests never follow redirects.** The key/token/download-password ride in custom
68
68
  `X-Oc-*` headers. `Net::HTTP` does not follow redirects by default — the SDK relies on that and
69
69
  only opts the no-secret download path into following redirects. `spec/security` proves the
data/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # API2Convert Ruby SDK
2
2
 
3
+ [![CI](https://github.com/QaamGo/api2convert-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/QaamGo/api2convert-ruby/actions/workflows/ci.yml)
4
+ [![Gem Version](https://img.shields.io/gem/v/api2convert)](https://rubygems.org/gems/api2convert)
5
+ ![Ruby](https://img.shields.io/badge/ruby-%E2%89%A5%203.1-red)
6
+ ![License](https://img.shields.io/badge/license-MIT-green)
7
+
3
8
  Official Ruby SDK for the [API2Convert](https://www.api2convert.com) file-conversion API.
4
9
  Convert, compress and transform images, documents, audio, video, ebooks, archives and CAD —
5
10
  and run operations like OCR, merge, thumbnail and website capture — in one line of code.
@@ -150,6 +155,44 @@ Live conformance tests hit the real API and are skipped unless a key is present:
150
155
  $ API2CONVERT_API_KEY=<your key> bundle exec rake spec:live
151
156
  ```
152
157
 
158
+ Each guide has a runnable, self-contained example under [`examples/`](examples/),
159
+ and the [live conformance suite](spec/live/conformance_spec.rb) mirrors every one
160
+ of them (same operation, plus assertions) so a published version is always
161
+ verified end to end. It runs automatically against the real API on every release
162
+ tag (see `.github/workflows/live-conformance.yml`).
163
+
164
+ | # | Example | What it shows |
165
+ |---|---------|---------------|
166
+ | 1 | [`quickstart.rb`](examples/quickstart.rb) | Convert a remote URL, fetch the job, download the output |
167
+ | 2 | [`convert_files.rb`](examples/convert_files.rb) | Browse the conversions catalog, then convert |
168
+ | 3 | [`uploading_files.rb`](examples/uploading_files.rb) | One-call upload + convert of a local file |
169
+ | 4 | [`job_lifecycle.rb`](examples/job_lifecycle.rb) | Drive create → add input → start → wait → outputs by hand |
170
+ | 5 | [`add_watermark.rb`](examples/add_watermark.rb) | Stamp a PDF with an image (two remote inputs) |
171
+ | 6 | [`create_thumbnails.rb`](examples/create_thumbnails.rb) | Render a thumbnail of the first PDF page |
172
+ | 7 | [`compress_files.rb`](examples/compress_files.rb) | Compress an image with the compress operation |
173
+ | 8 | [`create_archives.rb`](examples/create_archives.rb) | Bundle remote files into a ZIP |
174
+ | 9 | [`create_hashes.rb`](examples/create_hashes.rb) | Compute a file's SHA-256 checksum |
175
+ | 10 | [`extract_assets.rb`](examples/extract_assets.rb) | Extract embedded assets from a document |
176
+ | 11 | [`file_analysis.rb`](examples/file_analysis.rb) | Extract file metadata as JSON |
177
+ | 12 | [`compare_files.rb`](examples/compare_files.rb) | Diff two images with compare-image |
178
+ | 13 | [`capture_website.rb`](examples/capture_website.rb) | Screenshot a page with the screenshot engine |
179
+ | 14 | [`audio_operations.rb`](examples/audio_operations.rb) | Re-encode audio to AAC |
180
+ | 15 | [`image_operations.rb`](examples/image_operations.rb) | Resize an image |
181
+ | 16 | [`webhooks.rb`](examples/webhooks.rb) | Start an async job with a callback URL |
182
+ | 17 | [`presets.rb`](examples/presets.rb) | List saved conversion presets |
183
+ | 18 | [`statistics.rb`](examples/statistics.rb) | Read monthly API usage |
184
+ | 19 | [`rate-limits.rb`](examples/rate-limits.rb) | Inspect the account's contracts |
185
+ | 20 | [`authentication.rb`](examples/authentication.rb) | Verify the API key by listing jobs |
186
+
187
+ A companion [`webhook.rb`](examples/webhook.rb) is a tiny Rack receiver that
188
+ verifies the callback signature — the other side of example 16.
189
+
190
+ Run any example with your key in the environment:
191
+
192
+ ```console
193
+ $ API2CONVERT_API_KEY=<your key> ruby -Ilib examples/quickstart.rb
194
+ ```
195
+
153
196
  If your machine's Ruby is older than the gem targets, run the guardrail on a
154
197
  supported Ruby with the bundled `Dockerfile`:
155
198
 
data/docs/CHANGELOG.md CHANGED
@@ -4,6 +4,8 @@ All notable changes to the API2Convert Ruby SDK are documented here. The five
4
4
  official SDKs (PHP, Python, Java, Node.js, Ruby) version together against the
5
5
  shared [`SDK_CONTRACT.md`](SDK_CONTRACT.md).
6
6
 
7
- ## [Unreleased]
7
+ ## [10.2.1] - 2026-07-08
8
8
 
9
- - Initial development; not yet publicly released.
9
+ - Lock-step version bump to keep all API2Convert SDKs on 10.2.1. No library changes since 10.2.0
10
+ (the redirect / download-password hardening already shipped); added a runnable example per
11
+ documented guide and expanded the live-conformance suite to seven canonical scenarios.
data/docs/SDK_CONTRACT.md CHANGED
@@ -10,27 +10,40 @@ Two layers make up an SDK:
10
10
  (`openapi/api2convert.openapi.json`); an AI update may freely change it to match the spec.
11
11
  - **Hand-authored layer** — the ergonomics below (`convert`, upload, polling, download, webhook
12
12
  verification). These flows are **not** in the spec. Their **public signatures and semantics are
13
- fixed**: change them only when this document changes, and bump the major version when you do.
13
+ fixed**: change them only when this document changes. Adding a new **optional** parameter or
14
+ options-bag field that preserves every existing call site and behavior is an additive **minor**;
15
+ changing or removing an existing parameter, return type, or documented semantic is a **major**.
14
16
 
15
17
  > When the two disagree, this contract wins for the hand-authored layer; the spec wins for the
16
18
  > derived layer.
17
19
 
18
20
  ## Protocol facts (the API the SDK speaks)
19
21
 
20
- - Base URL `https://api.api2convert.com/v2`. Auth header `X-Oc-Api-Key: <key>` on account requests.
22
+ - Base URL `https://api.api2convert.com/v2`. Auth header `X-Api2convert-Api-Key: <key>` on account requests (canonical `X-Api2convert-*` names; the legacy `X-Oc-*` headers remain accepted by the API as permanent aliases).
21
23
  - **Create job** `POST /jobs` `{ conversion:[{category?,target,options?}], input?:[…], process:bool,
22
24
  callback?, notify_status?, download_passwords?:[…] }` → response includes `id`, per-job `token`,
23
25
  per-job upload `server`, and `status.code`. `download_passwords` protects every output of the job;
24
26
  any password in the list then unlocks its downloads. The API never returns the plaintext back.
25
27
  - **Upload** (not in the spec): `POST {server}/upload-file/{job_id}`, `multipart/form-data` field
26
- `file`, authenticated with the per-job **`X-Oc-Token`** header — never the account key.
28
+ `file`, authenticated with the per-job **`X-Api2convert-Token`** header — never the account key.
27
29
  - **Add remote input**: `POST /jobs/{id}/input` `{ type:'remote', source:'https://…' }`.
30
+ - **Cloud input** (import from customer storage): `POST /jobs/{id}/input` (or inline in `create`)
31
+ `{ type:'cloud', source:<provider>, parameters:{…}, credentials:{…} }`, `<provider> ∈ {amazons3,
32
+ azure, ftp, googlecloud}`; plus `{ type:'gdrive_picker', source:<drive-file-id>,
33
+ credentials:{token}, content_type? }` for Google Drive. The API validates a cloud descriptor
34
+ **asynchronously** — it accepts any descriptor on create (`201`) and later fails a bad one on the
35
+ input (`status:failed`, generic `code 99`); it never echoes a credential value.
36
+ - **Cloud output** (deliver to customer storage): a `conversion[]` may carry
37
+ `output_target:[{ type:<provider>, parameters:{…}, credentials:{…} }]`, `<provider> ∈ {amazons3,
38
+ googlecloud, azure, ftp, youtube, gdrive}`. `status` (`waiting|uploading|completed|failed`) is
39
+ server-set and read-only — never sent on create. The job reaches `completed` only after the upload
40
+ succeeds (a failed upload → `failed`); an output-target conversion produces **no** local output.
28
41
  - **Start**: `PATCH /jobs/{id}` `{ process:true }`.
29
42
  - **Poll**: `GET /jobs/{id}` → terminal when `status.code ∈ {completed, failed, canceled}`
30
43
  (`failed`/`canceled` are unsuccessful terminals; non-terminal: `created`, `incomplete`,
31
44
  `downloading`, `queued`, `processing`, and any unknown code). Poll with backoff; clamp the
32
45
  interval to a floor (never busy-loop) and the total wait to a ceiling (never poll unbounded).
33
- - **Download**: `GET output.uri` — self-contained, no auth; `X-Oc-Download-Password` header if set.
46
+ - **Download**: `GET output.uri` — self-contained, no auth; `X-Api2convert-Download-Password` header if set.
34
47
  - **Discover options**: `GET /conversions?category=&target=`.
35
48
  - **Errors**: HTTP body `{ "message": "…" }`; job-level `errors[]` / `warnings[]` of
36
49
  `{ source, id_source, code, message, details }`.
@@ -64,7 +77,7 @@ Two layers make up an SDK:
64
77
  - `contents(downloadPassword?) → binary`, `url() → string`, `output()`, `outputs()`.
65
78
  - **Download-password transparency**: a password supplied at conversion time (`convert(...,
66
79
  downloadPassword)`) or to `download(output, downloadPassword)` is remembered and sent as the
67
- `X-Oc-Download-Password` header on every download from that result/handle — callers do not
80
+ `X-Api2convert-Download-Password` header on every download from that result/handle — callers do not
68
81
  re-supply it. An explicit `downloadPassword` argument to `save()` / `contents()` overrides the
69
82
  remembered one for that call.
70
83
 
@@ -82,8 +95,39 @@ Two layers make up an SDK:
82
95
  missing/wrong signature. Empty secret skips verification.
83
96
  - `parse(rawBody) → WebhookEvent` — deserialize without verifying (pre-signed-webhooks).
84
97
 
98
+ ## Cloud storage connectors
99
+
100
+ The API imports inputs from and delivers outputs to customer-owned cloud storage. The SDK models the
101
+ wire descriptors above; per-provider keys are **not** validated synchronously server-side, so the
102
+ typed surface is the client's only pre-flight structure.
103
+
104
+ - **Provider vocabulary** — one shared `CloudProvider` concept (per-language spelling): `amazons3,
105
+ azure, ftp, gdrive, googlecloud, youtube`. It is **build-side vocabulary only** — read models keep
106
+ `source`/`type`/`status` as raw strings, and an unknown provider from the server round-trips
107
+ untyped (never throws).
108
+ - **Cloud input** — a `CloudInput` builder emits `{ type:cloud, source, parameters, credentials }`
109
+ and hands off to `addInput` / the create path. It ships per-provider named constructors whose
110
+ signatures carry each provider's required keys **verbatim** (flat/lowercase, as the API expects):
111
+ `amazonS3(bucket, file, accesskeyid, secretaccesskey)`,
112
+ `azure(container, file, accountname, accountkey)`, `ftp(host, file, username, password)`,
113
+ `googleCloud(projectid, bucket, file, keyfile)`. The required keys are **constructor arguments**,
114
+ not a runtime gate — the builder never rejects a descriptor the permissive server would accept, and
115
+ a generic `parameters`/`credentials` map stays reachable for optional/forward-compat keys. Google
116
+ Drive input uses `type:gdrive_picker` (`source` = the Drive file id, token in `credentials.token`),
117
+ carried by the generic `addInput` raw-map path this wave (no typed builder yet). `gdrive` and
118
+ `youtube` are **output-only** — they validate as an input `source` but have no downloader.
119
+ - **Cloud output** — an `OutputTarget` model (`type` = a `CloudProvider` + free-form
120
+ `parameters`/`credentials`) attaches to a conversion, both via `convert`/`convertAsync` (a new
121
+ optional `outputTargets` control, never merged into the options map) and the raw `jobs().create`
122
+ conversion map. It serializes `{ type, parameters, credentials }` and **omits `status`** on create.
123
+ Per-provider output factories are **not** in this wave (their keys live in a separate service and
124
+ diverge per provider). When any output target is set, `convert` returns the completed `Job` and
125
+ does **not** download — the conversion has no local output.
126
+ - **Read semantics** — `parameters` and the per-target `status` round-trip on read; `credentials`
127
+ are **never** surfaced (the API returns them empty; the SDK does not hydrate them).
128
+
85
129
  ## Cross-cutting semantics
86
- - **Auth**: account key as `X-Oc-Api-Key`; uploads use the per-job token.
130
+ - **Auth**: account key as `X-Api2convert-Api-Key`; uploads use the per-job token.
87
131
  - **Retries**: automatically retry with capped, jittered exponential backoff, honoring `Retry-After`
88
132
  (delay-seconds or HTTP-date form, clamped to a ceiling). `429` is retried for every method; `5xx`
89
133
  and network errors are retried only for idempotent methods (`GET`/`HEAD`/`PUT`/`DELETE`/`OPTIONS`/
@@ -97,3 +141,10 @@ Two layers make up an SDK:
97
141
  conversion-failed (carrying the job and its `errors`).
98
142
  - **Naming**: method names and option keys are identical across languages, adapted only to each
99
143
  language's idiom (camelCase / snake_case).
144
+ - **Credential redaction**: cloud `credentials` travel in the request body — never derive error text
145
+ from the request body, and mask the **whole `credentials` object** to `[REDACTED]` wherever a value
146
+ object could surface it: object inspection (`toString`/`repr`/`Debug`/`inspect`), any SDK-emitted
147
+ request log, and the decoded error body (belt-and-suspenders — the API does not echo credential
148
+ values). Also mask any `parameters` leaf whose key contains a sensitive token (`token, password,
149
+ passwd, secret, key, keyfile, credential, passphrase, sas, sig, signature`, case-insensitive).
150
+ Credentials ride in the plaintext body — user-attached request logging must redact its own.
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Add a Watermark — stamp a PDF with an image using two remote inputs.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/add_watermark.rb
6
+
7
+ require "api2convert"
8
+
9
+ PDF = "https://example-files.online-convert.com/document/pdf/example.pdf"
10
+ PNG = "https://example-files.online-convert.com/raster%20image/png/example.png"
11
+
12
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
13
+
14
+ # Create a job with two inputs (the document and the stamp image) and start it.
15
+ job = client.jobs.create(
16
+ {
17
+ "process" => true,
18
+ "input" => [
19
+ { "type" => "remote", "source" => PDF },
20
+ { "type" => "remote", "source" => PNG }
21
+ ],
22
+ "conversion" => [
23
+ {
24
+ "category" => "document",
25
+ "target" => "pdf",
26
+ "options" => { "stamp" => true, "alignment" => "center" }
27
+ }
28
+ ]
29
+ }
30
+ )
31
+
32
+ done = client.jobs.wait(job.id)
33
+ puts "job #{done.id} is #{done.status.code}"
34
+
35
+ outputs = client.jobs.outputs(job.id)
36
+ outputs.each { |output| puts output.uri }
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Audio Operations — re-encode a WAV to AAC with explicit codec settings.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/audio_operations.rb
6
+
7
+ require "api2convert"
8
+
9
+ WAV = "https://example-files.online-convert.com/audio/wav/example.wav"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ result = client.convert(
14
+ WAV,
15
+ "aac",
16
+ { "audio_codec" => "aac", "audio_bitrate" => 192, "channels" => "stereo", "frequency" => 44_100 },
17
+ category: "audio"
18
+ )
19
+
20
+ path = result.save("output/")
21
+ puts "saved #{path} (#{File.size(path)} bytes)"
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Authentication — verify your API key by listing your jobs.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/authentication.rb
6
+
7
+ require "api2convert"
8
+
9
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
10
+
11
+ # A successful, authenticated call returns your jobs (empty on a fresh account).
12
+ jobs = client.jobs.list
13
+ puts "authenticated: #{jobs.length} job(s) visible"
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Capture a Website — screenshot a page with the screenshot engine.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/capture_website.rb
6
+
7
+ require "api2convert"
8
+
9
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
10
+
11
+ job = client.jobs.create(
12
+ {
13
+ "process" => true,
14
+ "input" => [
15
+ {
16
+ "type" => "remote",
17
+ "source" => "https://www.online-convert.com",
18
+ "engine" => "screenshot",
19
+ "options" => { "screen_width" => 1280, "screen_height" => 1024, "device_scale_factor" => 1 }
20
+ }
21
+ ],
22
+ "conversion" => [{ "category" => "image", "target" => "png" }]
23
+ }
24
+ )
25
+
26
+ done = client.jobs.wait(job.id)
27
+ puts "job #{done.id} is #{done.status.code}"
28
+
29
+ client.jobs.outputs(job.id).each { |output| puts output.uri }
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Compare Files — diff two images with the compare-image operation.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/compare_files.rb
6
+
7
+ require "api2convert"
8
+
9
+ JPG_SMALL = "https://example-files.online-convert.com/raster%20image/jpg/example_small.jpg"
10
+ JPG = "https://example-files.online-convert.com/raster%20image/jpg/example.jpg"
11
+
12
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
13
+
14
+ job = client.jobs.create(
15
+ {
16
+ "process" => true,
17
+ "input" => [
18
+ { "type" => "remote", "source" => JPG_SMALL },
19
+ { "type" => "remote", "source" => JPG }
20
+ ],
21
+ "conversion" => [
22
+ {
23
+ "category" => "operation",
24
+ "target" => "compare-image",
25
+ "options" => { "method" => "ssim", "threshold" => 5, "diff_color" => "red" }
26
+ }
27
+ ]
28
+ }
29
+ )
30
+
31
+ done = client.jobs.wait(job.id)
32
+ puts "job #{done.id} is #{done.status.code}"
33
+
34
+ client.jobs.outputs(job.id).each { |output| puts output.uri }
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Compress Files — shrink an image with the compress operation.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/compress_files.rb
6
+
7
+ require "api2convert"
8
+
9
+ JPG = "https://example-files.online-convert.com/raster%20image/jpg/example.jpg"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ result = client.convert(
14
+ JPG, "compress", { "compression_level" => "high" }, category: "operation"
15
+ )
16
+
17
+ path = result.save("output/")
18
+ puts "saved #{path} (#{File.size(path)} bytes)"
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Convert Files — browse the conversions catalog, then convert.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/convert_files.rb
6
+
7
+ require "api2convert"
8
+
9
+ JPG = "https://example-files.online-convert.com/raster%20image/jpg/example.jpg"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ # The whole catalog: every supported target and its options.
14
+ all = client.conversions.list
15
+ puts "#{all.length} conversions available"
16
+
17
+ # Narrow it down: which conversions produce a PNG image?
18
+ png = client.conversions.list("image", "png")
19
+ puts "#{png.length} way(s) to produce png"
20
+
21
+ # Now convert a JPG to PNG.
22
+ result = client.convert(JPG, "png", category: "image")
23
+ path = result.save("convert-files-output.png")
24
+ puts "saved #{path} (#{File.size(path)} bytes)"
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create Archives — bundle several remote files into a single ZIP.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/create_archives.rb
6
+
7
+ require "api2convert"
8
+
9
+ PDF = "https://example-files.online-convert.com/document/pdf/example.pdf"
10
+ PNG = "https://example-files.online-convert.com/raster%20image/png/example.png"
11
+
12
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
13
+
14
+ job = client.jobs.create(
15
+ {
16
+ "process" => true,
17
+ "input" => [
18
+ { "type" => "remote", "source" => PDF },
19
+ { "type" => "remote", "source" => PNG }
20
+ ],
21
+ "conversion" => [{ "category" => "archive", "target" => "zip" }]
22
+ }
23
+ )
24
+
25
+ done = client.jobs.wait(job.id)
26
+ puts "job #{done.id} is #{done.status.code}"
27
+
28
+ outputs = client.jobs.outputs(job.id)
29
+ outputs.each { |output| puts output.uri }
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create Hashes — compute the SHA-256 checksum of a remote file.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/create_hashes.rb
6
+
7
+ require "api2convert"
8
+
9
+ ZIP = "https://example-files.online-convert.com/archive/zip/example.zip"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ result = client.convert(ZIP, "sha256", category: "hash")
14
+
15
+ # The hash is returned as the output file's contents.
16
+ puts "sha256: #{result.contents}"
17
+
18
+ path = result.save("output/")
19
+ puts "saved #{path} (#{File.size(path)} bytes)"
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create Thumbnails — render a thumbnail of the first PDF page.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/create_thumbnails.rb
6
+
7
+ require "api2convert"
8
+
9
+ PDF = "https://example-files.online-convert.com/document/pdf/example.pdf"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ result = client.convert(
14
+ PDF,
15
+ "thumbnail",
16
+ { "thumbnail_target" => "png", "width" => 300, "pages" => "first", "dpi" => 150 },
17
+ category: "operation"
18
+ )
19
+
20
+ # Save into a directory so the API-provided filename is kept.
21
+ path = result.save("output/")
22
+ puts "saved #{path} (#{File.size(path)} bytes)"
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Extract Assets — pull the embedded assets out of a document.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/extract_assets.rb
6
+
7
+ require "api2convert"
8
+
9
+ DOCX = "https://example-files.online-convert.com/document/docx/example.docx"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ result = client.convert(DOCX, "extract-assets", category: "operation")
14
+ puts "job #{result.job.id} is #{result.job.status.code}"
15
+
16
+ result.outputs.each { |output| puts output.uri }
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # File Analysis — extract a file's metadata as JSON.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/file_analysis.rb
6
+
7
+ require "api2convert"
8
+
9
+ JPG = "https://example-files.online-convert.com/raster%20image/jpg/example.jpg"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ result = client.convert(JPG, "json", category: "metadata")
14
+ puts "job #{result.job.id} is #{result.job.status.code}"
15
+
16
+ # The analysis result is the output file's JSON body.
17
+ puts result.contents
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Image Operations — resize an image with the resize-image operation.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/image_operations.rb
6
+
7
+ require "api2convert"
8
+
9
+ JPG = "https://example-files.online-convert.com/raster%20image/jpg/example.jpg"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ result = client.convert(
14
+ JPG,
15
+ "resize-image",
16
+ { "width" => 800, "height" => 600, "resize_by" => "px", "resize_handling" => "keep_aspect_ratio_crop" },
17
+ category: "operation"
18
+ )
19
+
20
+ path = result.save("output/")
21
+ puts "saved #{path} (#{File.size(path)} bytes)"
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Job Lifecycle — drive create -> add input -> start -> wait -> outputs by hand.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/job_lifecycle.rb
6
+
7
+ require "api2convert"
8
+
9
+ JPG = "https://example-files.online-convert.com/raster%20image/jpg/example.jpg"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ # Stage a job (process: false) so we can attach inputs before starting.
14
+ job = client.jobs.create(
15
+ { "process" => false, "conversion" => [{ "category" => "image", "target" => "png" }] }
16
+ )
17
+ puts "created job #{job.id}"
18
+
19
+ # Attach a remote input, then start processing.
20
+ client.jobs.add_input(job.id, { "type" => "remote", "source" => JPG })
21
+ client.jobs.start(job.id)
22
+
23
+ # Poll to a terminal status (raises on a failed job by default).
24
+ done = client.jobs.wait(job.id)
25
+ puts "job #{done.id} is #{done.status.code}"
26
+
27
+ # List the produced outputs.
28
+ outputs = client.jobs.outputs(job.id)
29
+ outputs.each { |output| puts output.uri }
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Presets — list your saved conversion presets.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/presets.rb
6
+
7
+ require "api2convert"
8
+
9
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
10
+
11
+ presets = client.presets.list(category: "video", target: "mp4")
12
+ puts "#{presets.length} preset(s)"
13
+
14
+ presets.each { |preset| puts "#{preset.id}: #{preset.name} -> #{preset.target}" }
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Quickstart — convert a remote file, inspect the job, download the result.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/quickstart.rb
6
+
7
+ require "api2convert"
8
+
9
+ JPG = "https://example-files.online-convert.com/raster%20image/jpg/example.jpg"
10
+
11
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
12
+
13
+ # One-call convert of a remote URL (create -> poll -> ready to download).
14
+ result = client.convert(JPG, "png", category: "image")
15
+
16
+ # Fetch the finished job by id and print its status.
17
+ job = client.jobs.get(result.job.id)
18
+ puts "job #{job.id} is #{job.status.code}"
19
+
20
+ # Download the produced output.
21
+ path = result.save("quickstart-output.png")
22
+ puts "saved #{path} (#{File.size(path)} bytes)"
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Rate Limits — inspect your account's contracts (quotas and limits).
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/rate_limits.rb
6
+
7
+ require "api2convert"
8
+
9
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
10
+
11
+ contracts = client.contracts.get
12
+ puts contracts.inspect
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Statistics — read your API usage for a given month.
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/statistics.rb
6
+
7
+ require "api2convert"
8
+
9
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
10
+
11
+ stats = client.stats.month("2026-06")
12
+ puts stats.inspect
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Uploading Files — convert a local file in one call (convert() uploads it).
4
+ #
5
+ # API2CONVERT_API_KEY=<your key> ruby -Ilib examples/uploading_files.rb
6
+
7
+ require "api2convert"
8
+ require "base64"
9
+ require "tmpdir"
10
+
11
+ # A minimal valid 1x1 PNG so the example needs no binary fixture on disk.
12
+ ONE_PX_PNG = Base64.decode64(
13
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
14
+ )
15
+
16
+ client = Api2Convert::Client.new # reads API2CONVERT_API_KEY
17
+
18
+ Dir.mktmpdir("a2c-upload") do |dir|
19
+ source = File.join(dir, "pixel.png")
20
+ File.binwrite(source, ONE_PX_PNG)
21
+
22
+ # Hand convert() a local path — it stages the job, uploads the file to the
23
+ # per-job upload server, starts it and polls to completion.
24
+ result = client.convert(source, "png", category: "image")
25
+ path = result.save("uploading-files-output.png")
26
+ puts "saved #{path} (#{File.size(path)} bytes)"
27
+ end