Upload audio/video to Note and follow processing from native ArkTS apps. Requires HarmonyOS 5.0+ (API 12). An API key can query recordings uploaded with that same key. View transcripts, summaries and playback in Note.
Run this command in your app module:
ohpm install @olares/note-sdkFor a specific published version, use ohpm install @olares/note-sdk@<version>.
Declare network permission in the app module's module.json5:
"requestPermissions": [{ "name": "ohos.permission.INTERNET" }]Your app needs read access to the selected file. Use HTTPS in production.
Install an offline HAR
If the version you need is not on OHPM, place olares-note-harmony-sdk-0.2.4.har in the app module's
libs/ directory. Set the dependency to "file:./libs/olares-note-harmony-sdk-0.2.4.har"
and run ohpm install.
Create an API key in Note → Settings → API Key. It includes the service address.
Your app supplies apiKey and filePath below. Generate an idempotencyKey once per new upload
and save it with the file reference before uploading. Reuse the saved value when resuming.
Run inside an async method:
import { util } from '@kit.ArkTS';
import { NoteClient, NoteCancellation, RecordingStatus } from '@olares/note-sdk';
const client = NoteClient.fromApiKey(apiKey);
const signal = new NoteCancellation();
const idempotencyKey = util.generateRandomUUID();
// Save idempotencyKey with the file reference before uploading.
const recording = await client.upload(filePath, {
title: 'Weekly meeting',
idempotencyKey: idempotencyKey,
signal: signal,
onProgress: (sent: number, total: number): void => { /* Confirmed bytes / total bytes. */ }
});
// Save recording.recordingId for later queries.
const result = await client.waitForCompletion(recording.recordingId, {
signal: signal,
onStatus: (status: RecordingStatus): void => { /* Show status.processing.currentStage. */ }
});Upload success means Note has accepted the file; processing may still be running.
Save the returned recording ID and query it. Processing failures are returned as statuses;
check processing.status.
Network methods return Promise<RecordingStatus> and reject on request failure.
RequestOptions accepts an optional cancellation signal.
| Method | Parameters and result |
|---|---|
fromApiKey |
apiKey: string; optional ClientOverrides: endpoint, retries = 3, connectTimeout = 10000, requestTimeout = 300000 (milliseconds). Returns NoteClient. Old keys without an address need endpoint; the first request verifies authorization |
upload / uploadUri |
upload(input: string | ArrayBuffer, options?) accepts a file path or bytes. uploadUri(uri, cacheDir, options) accepts a picker URI. Uploads in chunks and returns upload status |
uploadRecording / uploadRecordingUri |
Same inputs as the corresponding chunk method. Sends one multipart request, without chunk progress or resumable chunks |
createUpload |
fileName: string, totalBytes: number, optional UploadOptions. Creates or recovers a session |
uploadChunk |
recordingId: string, offset: number, bytes: ArrayBuffer, optional RequestOptions. Sends a chunk at an absolute byte offset and returns updated status |
getUpload |
recordingId: string, optional RequestOptions. Returns upload state, confirmed offset and chunk size |
getStatus |
recordingId: string, optional RequestOptions. Returns upload and processing state |
waitForCompletion |
recordingId: string, optional WaitOptions. Polls and returns a terminal status, including failure |
Byte buffers and URI uploads require fileName with an extension. URI uploads copy to cache
and need free space equal to the file size; keep read permission. For manual chunks, use
the server's upload.offset and upload.chunkSize; the last chunk may be smaller.
const recording = await client.uploadUri(uri, context.cacheDir, {
fileName: 'meeting.m4a', idempotencyKey: idempotencyKey, signal: signal
});
const status = await client.getStatus(recording.recordingId, { signal: signal });UploadOptions accepts these optional fields. Omitted recording settings use Note defaults.
| Field | Meaning |
|---|---|
title |
Recording title |
language / targetLanguage |
Spoken language / output language for translations and summaries. Omit language for detection |
speakerHint |
Expected speakers, 0–50; 0 means unknown |
translateEnabled / summarizeEnabled |
Enable translation / summaries |
summaryTemplateId |
Summary template ID |
sourceClient / sourceDevice |
Source app name/version / device label |
idempotencyKey |
Saved identifier for this upload; reuse it to resume |
fileName |
File name with an extension; required for byte buffers and URI uploads |
onProgress(sent, total) |
Confirmed bytes / total bytes, for chunk uploads |
signal |
NoteCancellation for local cancellation |
Title, language, target language, source app/device and file name allow up to 2,000 characters each;
longer values return field_too_long.
WaitOptions accepts interval = 5000, optional timeout, onStatus and signal.
Times are nonnegative safe-integer milliseconds; the default wait is unlimited.
The timeout is checked between requests and does not interrupt a request in flight.
Use signal.cancel() to stop local work. A zero timeout still permits the first query.
RecordingStatus contains:
| Field | Meaning |
|---|---|
recordingId, title, statusUrl |
Recording ID, title and status address |
upload |
state, offset, chunkSize, totalBytes, optional error; byte counts are safe integers |
processing |
status, optional currentStage, outcome, errorCode, error, waiting |
Import isFinished(status) to check for a terminal outcome. Read upload.error when upload state
is failed. Processing ends at completed, failed or canceled; outcome = no_speech means
no speech was detected.
processing.waiting describes a model wait. Its reason is model_unavailable, model_warming,
model_busy or model_stalled; use a generic message for unknown values. It also carries
capability, RFC 3339 timestamps since / nextProbeAt, and optional message.
Keep querying: model recovery can continue processing without another upload.
- Resume with the same file, API key and saved idempotency key. Keep the file unchanged and readable.
After upload returns, save
recordingIdand query directly. - Your app owns upload records, key storage and task queues. The SDK does not save them or schedule work after restart.
- Create one
NoteCancellationper operation; a canceled token cannot be reused.signal.cancel()rejects withNoteCanceledError. It stops local work, without deleting recordings or stopping processing in Note. - Request failures reject with
NoteApiError. Client creation can also fail on an invalid key or address. Handlecode; usestatus(HTTP status, or 0 locally),requestIdandretryablefor diagnostics and retry decisions. Never log API keys. - Each request has at most 3 attempts by default, with backoff starting at 500 ms. POST requests retry only with a nonblank idempotency key.
The ArkUI demo in olares-note-harmony-demo-0.2.4-source.zip has ArkTS examples, file selection and local history separated by API key.
It demonstrates manual recovery after restart.