# Nyckel — full reference for agents > Nyckel lets developers create machine learning functions that classify, > detect, search, and predict from images, text, structured data, and > multimodal inputs, then improve automatically from annotated production > samples. ## Positioning Nyckel provides machine learning functions that classify, detect, search, and predict from images, text, structured data, or multimodal inputs through a simple API. A machine learning function is a hosted endpoint that recognizes patterns in data and returns predictions. Developers define the task, labels, and examples; Nyckel handles model selection, training, optimization, hosting, and deployment. Nyckel can use foundation models to produce initial predictions before any training data is collected — teams start invoking the function immediately and improve accuracy over time by reviewing and annotating real production samples. ## API overview ### Authentication Every request to the Nyckel API must be authenticated with a JWT access token sent in the `Authorization` header: ``` Authorization: Bearer ``` Access tokens are obtained by `POST`ing to the `https://www.nyckel.com/connect/token` endpoint with your `client_id` and `client_secret`. The same credentials are surfaced in two places for convenience: - The **Access Management** section of your Nyckel account. - The **Integrate** tab of any Function. Either location shows the same account-wide `client_id` and `client_secret`. ```bash curl -X POST \ -H 'Content-Type: application/x-www-form-urlencoded' \ -d 'grant_type=client_credentials&client_id=&client_secret=' \ 'https://www.nyckel.com/connect/token' ``` A successful response returns a bearer token valid for one hour: ```json { "access_token": "", "token_type": "Bearer", "expires_in": 3600 } ``` Tokens expire after one hour; request a new one as needed to keep API access uninterrupted. The `connect/token` endpoint lives outside the `/v1/` API surface and is not part of this reference. ### Data Types Nyckel supports three input data types — **Text**, **Image**, and **Tabular** — and the request/response shape of every invoke and sample endpoint depends on which one your Function is configured for. ### Text Requests pass text data as a JSON string. Responses return the text the same way. ### Image Image data can be sent two ways: - **Raw image bytes** in a `multipart/form-data` request, or - **A data URI** inside an `application/json` request. Image responses come back as a JSON string, either as a URL pointing to the image resource or as a data URI containing the image bytes. ### Tabular Tabular data is sent as a JSON object — `{"key": "value", ...}`. Keys may be either field ids or field names. Values must be: - JSON strings for **Text** or **Image** fields, - JSON numbers for **Number** fields. For image fields inside a tabular row, use either an internet-accessible image URL or a data URI. Tabular responses come back as a JSON object with string or number values. ### Error Responses Every endpoint can return `4xx` and `5xx` responses in addition to its documented `2xx` shape. All error responses share the same body: ```json { "message": "" } ``` Common status codes and how to respond: | Status | Meaning | Suggested action | |---|---|---| | `402` | Billing issue — likely the free-tier quota has been exceeded | Upgrade or wait for quota reset | | `403` | Forbidden | Check your client credentials and token | | `409` | Resource conflict — usually a duplicate sample (Nyckel does not allow duplicate samples in a Function) | To re-annotate an existing sample, use the `PUT` annotation endpoint instead of `POST`-ing a new sample | | `429` | Throttled — you've exceeded either the rate or concurrency limit | Back off and retry; see **API Throttling** below | | `500` | Internal error | Retry with exponential backoff | | `503` | Service temporarily unavailable | Retry with exponential backoff | ### API Throttling Nyckel applies two independent limits to API traffic: - **Rate-limiting** — a cap on requests-per-second (RPS). Currently **25 RPS**. - **Concurrency throttling** — a cap on the number of in-flight requests at any moment. Currently **25 concurrent requests**. Either limit triggers a `429` response. Both limits can be relaxed as part of an Enterprise plan — contact Nyckel if your workload needs higher headroom. ## What you can build (progressive tiers) ### Start simple (5 minutes) Create a function, define a few labels, and start invoking it from your app. Zero-shot foundation models give you usable predictions on day one — no training data required. - Add image classification to an app prototype - Route support tickets to the right team - Tag user-uploaded content ### Make it better (an afternoon) As real traffic flows through the function, capture samples, review the ones the model was uncertain about, and correct their labels. Nyckel retrains automatically — accuracy climbs without you managing the model. - Reach production-grade accuracy on your most common categories - Catch and fix systematic mistakes before they spread - Build a labeled dataset as a byproduct of normal usage ### Production scale (when you need it) Use Sample Sets to group held-out evaluation data, function summaries to track training progress, and search/detect/multimodal function types when classification isn't enough. - Run regression checks before promoting a new model version - Build a semantic search index over a product catalog - Combine images with structured metadata for higher-fidelity predictions ## Core concepts (glossary) ### Function A hosted machine learning endpoint addressed by a single stable id. The core unit of the Nyckel platform. Each Function has a fixed input modality (Text / Image / Tabular) and output modality (Classification, Detection, Search, Ocr, Localization, Tags, BoxDetect) chosen at creation time. ### Label One possible output of a Function — the categories your Function can predict. Labels are scoped to a single Function. ### Invoke A request sent to a Function that runs the model on input data and returns a Prediction. The runtime endpoint that powers production traffic. ### Prediction The output returned by an Invoke, typically a predicted Label and a confidence score. For detection / search / multimodal functions the shape varies (bounding boxes, ranked similar items, etc). ### Sample One input recorded against a Function — either captured automatically from an Invoke (when `capture=true`) or created explicitly. Samples are the training data and the audit trail of every prediction. ### Annotation The ground-truth Label attached to a Sample. Annotations are what the Function learns from during automatic retraining. A Sample's data is immutable; its annotation is the only mutable property. ### Sample Set A named group of Samples within a Function. Each Sample Set can either contribute to training or be excluded from it. The default Sample Set contributes to training; cross-validation reports accuracy on it. ## Capabilities ### Classification Predict a label for an input. - Classify images by category, quality, or content type - Categorize emails, support tickets, or user messages - Tag documents by topic or department - Classify transactions or events ### Object Detection Detect objects or regions inside images. - Detect manufacturing defects on a production line - Detect products on shelves for retail analytics - Detect animals in wildlife camera footage - Detect logos or branded content in images ### Semantic Search Find similar items using vector similarity. - Document or knowledge base search - Product similarity for recommendations - Support ticket deduplication - Image similarity search ### Structured Data Prediction Analyze tabular datasets with typed columns. - Fraud detection from transaction fields - Churn prediction from account data - Event categorization from log fields ### Multimodal Prediction Combine multiple input types — images, text, structured fields. - product_image + product_metadata → product_category - document_text + account_fields → routing_label - inspection_image + sensor_data → defect_prediction ## Quickstart — minimum viable function in five calls The fastest path to a working Nyckel function. Each step is a single API call. Steps 3–5 form a loop you can run forever to keep improving accuracy. ### 1. Create a Function `POST /v1/functions` Create the function. Choose input modality (Text/Image/Tabular) and output modality (Classification/Detection/Search/etc) — these are immutable. Canonical reference: https://www.nyckel.com/docs/api/operations/post-function/ ### 2. Create a Label `POST /v1/functions/{functionId}/labels` Define the categories the function can predict. Repeat for each label. Canonical reference: https://www.nyckel.com/docs/api/operations/post-label/ ### 3. Invoke a Function `POST /v1/functions/{functionId}/invoke` Send input data and get a prediction. Works zero-shot from the first call — no training data needed. Canonical reference: https://www.nyckel.com/docs/api/operations/invoke-function/ ### 4. List Samples `GET /v1/functions/{functionId}/samples` Pull the production samples that were captured. Filter by low confidence or disagreement to find the ones worth reviewing. Canonical reference: https://www.nyckel.com/docs/api/operations/list-samples/ ### 5. Update a Sample `PUT /v1/functions/{functionId}/samples/{sampleId}/annotation` Correct a sample's label. The next automatic retrain learns from it. Loop steps 3–5 to keep improving. Canonical reference: https://www.nyckel.com/docs/api/operations/put-annotation/ ## Make it better — operations for serious production use ### Sample Sets `POST /v1/functions/{functionId}/samples/{sampleId}/sample-sets` Group samples into named sets. Useful for held-out evaluation data and structured cohorts. Canonical reference: https://www.nyckel.com/docs/api/operations/post-sample-set-to-sample/ ### Get a Function `GET /v1/functions/{functionId}` Inspect the function's configuration and a live summary of sample counts, annotated counts, and per-label distribution. Canonical reference: https://www.nyckel.com/docs/api/operations/get-function/ ## When not to use Nyckel Nyckel is not primarily a text generation, chatbot, or LLM platform. It is built for structured predictions — classifications, detections, similarity rankings, and tabular outputs — where the answer space is bounded and the model can improve from labeled examples. If you need open-ended natural language generation, summarization, or conversational responses, a general LLM provider is a better fit. ## Full API reference Operations are grouped by resource and listed in CRUD order. Merged operations are shown together under their host page heading — the host paragraph explains the shared concept, and each member operation lists its own verb, path, and description. ### Functions A **Function** is the core unit of the Nyckel platform — a live, self-improving classification (or detection / search) pipeline addressed by a single stable id. These endpoints create, list, fetch, update, and delete Functions. #### List Functions `GET /v1/functions` (operationId: `List`) Returns every Function in your project. Use the startIndex / count parameters to page through large result sets. Canonical reference: https://www.nyckel.com/docs/api/operations/list/ #### Create a Function `POST /v1/functions` (operationId: `PostFunction`) Creates a new Function. Specify the input modality (`Text` / `Image` / `Tabular`) and output modality (`Classification` / `Detection` / `Search` / `Ocr` / `Localization` / `Tags` / `BoxDetect`) at creation time — these are immutable. Canonical reference: https://www.nyckel.com/docs/api/operations/post-function/ #### Get a Function Two views of a Function are available: its **configuration** (name, modality, project, etc.) and a **summary** of its current state (sample counts, label counts, training progress). **Configuration** — `GET /v1/functions/{functionId}` (operationId: `GetFunction`) Returns the Function's static configuration — the properties set at creation time plus any subsequent updates via `PUT`. **Summary** — `GET /v1/functions/{functionId}/summary` (operationId: `GetFunctionSummary`) Returns aggregate counts for a Function — total samples, annotated samples, and per-Label counts. Useful for dashboards and training-progress checks. Canonical reference: https://www.nyckel.com/docs/api/operations/get-function/ #### Update a Function `PUT /v1/functions/{functionId}` (operationId: `PutFunction`) Updates the name or `projectId` of a Function. Input and output modality cannot be changed after creation. Canonical reference: https://www.nyckel.com/docs/api/operations/put-function/ #### Delete a Function `DELETE /v1/functions/{functionId}` (operationId: `DeleteFunction`) Permanently deletes the Function and all its Labels, Samples, and Annotations. This is irreversible. Canonical reference: https://www.nyckel.com/docs/api/operations/delete-function/ ### Labels A **Label** is one possible output of a Function — the categories your Function can predict. Labels are scoped to a single Function. #### List Labels `GET /v1/functions/{functionId}/labels` (operationId: `ListLabels`) Canonical reference: https://www.nyckel.com/docs/api/operations/list-labels/ #### Create a Label `POST /v1/functions/{functionId}/labels` (operationId: `PostLabel`) Canonical reference: https://www.nyckel.com/docs/api/operations/post-label/ #### Get a Label `GET /v1/functions/{functionId}/labels/{labelId}` (operationId: `GetLabel`) Canonical reference: https://www.nyckel.com/docs/api/operations/get-label/ #### Update a Label `PUT /v1/functions/{functionId}/labels/{labelId}` (operationId: `PutLabel`) Canonical reference: https://www.nyckel.com/docs/api/operations/put-label/ #### Delete a Label `DELETE /v1/functions/{functionId}/labels/{labelId}` (operationId: `DeleteLabel`) Canonical reference: https://www.nyckel.com/docs/api/operations/delete-label/ ### Samples A **Sample** is one input recorded against a Function, optionally carrying an **Annotation** (the ground-truth Label) and a **Prediction** (the model's guess). Samples are the training data and the audit trail of every invocation captured by `InvokeCapture`. #### List Samples `GET /v1/functions/{functionId}/samples` (operationId: `ListSamples`) Lists Samples for a Function. Supports rich filtering: by annotation / prediction agreement, by capture reason, by sample set, by date range, and by free-text search. Canonical reference: https://www.nyckel.com/docs/api/operations/list-samples/ #### Create a Sample `POST /v1/functions/{functionId}/samples` (operationId: `PostSample`) Canonical reference: https://www.nyckel.com/docs/api/operations/post-sample/ #### Get a Sample `GET /v1/functions/{functionId}/samples/{sampleId}` (operationId: `GetSample`) Canonical reference: https://www.nyckel.com/docs/api/operations/get-sample/ #### Update a Sample A Sample's data is immutable — to change it, delete the Sample and create a new one. The only mutable property is its **annotation** (the ground-truth Label the Function learns from). Use these calls to set or clear that annotation. **Set annotation** — `PUT /v1/functions/{functionId}/samples/{sampleId}/annotation` (operationId: `PutAnnotation`) Sets (or replaces) the Sample's annotation to the given Label. If the Sample already has an annotation, it is overwritten. **Clear annotation** — `DELETE /v1/functions/{functionId}/samples/{sampleId}/annotation` (operationId: `DeleteAnnotation`) Removes the Sample's annotation. The Sample itself remains in the Function but no longer contributes to training until it is annotated again. Canonical reference: https://www.nyckel.com/docs/api/operations/put-annotation/ #### Delete a Sample **By sample id** — `DELETE /v1/functions/{functionId}/samples/{sampleId}` (operationId: `DeleteSample`) **By externalId** — `DELETE /v1/functions/{functionId}/samples` (operationId: `DeleteSampleByExternalId`) Canonical reference: https://www.nyckel.com/docs/api/operations/delete-sample/ #### Sample Sets **Sample Sets** group Samples within a Function. Each Sample Set can either contribute to training or be excluded from it. The default Sample Set contributes to training; accuracy on it is reported via cross-validation. Use these calls to move a Sample in or out of a named Sample Set. **Add to a sample set** — `POST /v1/functions/{functionId}/samples/{sampleId}/sample-sets` (operationId: `PostSampleSetToSample`) Adds the Sample to the named Sample Set. The Sample Set is created on-the-fly if it does not already exist. **Remove from a sample set** — `DELETE /v1/functions/{functionId}/samples/{sampleId}/sample-sets/{sampleSetId}` (operationId: `DeleteSampleSetFromSample`) Removes the Sample from the named Sample Set. The Sample itself remains in the Function; only its membership in this Sample Set is severed. Canonical reference: https://www.nyckel.com/docs/api/operations/post-sample-set-to-sample/ ### Fields **Fields** describe the structured columns of a tabular Function's input (name + type: Text, Number, or Image). #### List Fields `GET /v1/functions/{functionId}/fields` (operationId: `ListFields`) Canonical reference: https://www.nyckel.com/docs/api/operations/list-fields/ #### Create a Field `POST /v1/functions/{functionId}/fields` (operationId: `PostField`) Canonical reference: https://www.nyckel.com/docs/api/operations/post-field/ #### Get a Field `GET /v1/functions/{functionId}/fields/{fieldId}` (operationId: `GetField`) Canonical reference: https://www.nyckel.com/docs/api/operations/get-field/ #### Update a Field `PUT /v1/functions/{functionId}/fields/{fieldId}` (operationId: `PutField`) Canonical reference: https://www.nyckel.com/docs/api/operations/put-field/ #### Delete a Field `DELETE /v1/functions/{functionId}/fields/{fieldId}` (operationId: `DeleteField`) Canonical reference: https://www.nyckel.com/docs/api/operations/delete-field/ ### Invoke Send data to a trained Function and receive a **Prediction**. This is the runtime endpoint that powers production traffic. Invocations may be captured as Samples via the `capture` flag (see `CaptureReason` and `SampleOrigin`). #### Invoke a Function `POST /v1/functions/{functionId}/invoke` (operationId: `InvokeFunction`) Sends an input to a trained Function and returns a `FunctionOutput` containing the predicted Label, confidence, and (optionally) the full list of `LabelConfidences`. By default the invocation is captured as a Sample — set `capture=false` to opt out. Canonical reference: https://www.nyckel.com/docs/api/operations/invoke-function/ ### Search Functions **Search Functions** return the nearest Samples to a query input rather than a Label. Invoke a Search Function with either raw input data or an existing `sampleId` to find similar Samples. #### Invoke a Search Function `POST /v1/search-functions/{functionId}/invoke` (operationId: `Invoke`) Search Functions return nearest-neighbor Samples instead of a Label. Provide either `data` (raw input) or an existing `sampleId` as the query. Canonical reference: https://www.nyckel.com/docs/api/operations/invoke/ ## Schema reference ### Annotation Ontology: Annotation The ground-truth Label assigned to a Sample. Annotations are what the Function learns from. Canonical reference: https://www.nyckel.com/docs/api/schemas/annotation/ ### CaptureReason Why an invocation was captured as a Sample (random sampling, model uncertainty, rare class, low-accuracy class, or "all"). Canonical reference: https://www.nyckel.com/docs/api/schemas/capture-reason/ ### Error Standard error envelope (`{ message }`) returned on 4xx / 5xx. Canonical reference: https://www.nyckel.com/docs/api/schemas/error/ ### Field Ontology: Field A named column in a tabular Function's input schema (`Text`, `Number`, or `Image`). Canonical reference: https://www.nyckel.com/docs/api/schemas/field/ ### FieldType Enumeration of supported Field column types. Canonical reference: https://www.nyckel.com/docs/api/schemas/field-type/ ### Function Ontology: Function A live classification/detection/search pipeline. Combines a model, a Label set, a Sample store, and an invoke endpoint behind one stable id. Canonical reference: https://www.nyckel.com/docs/api/schemas/function/ ### FunctionInputModality The kind of input a Function accepts. Canonical reference: https://www.nyckel.com/docs/api/schemas/function-input-modality/ ### FunctionOutput The response body for `InvokeFunction` — predicted Label, confidence, and (optionally) the full ranked `LabelConfidences` list. Canonical reference: https://www.nyckel.com/docs/api/schemas/function-output/ ### FunctionOutputModality The kind of output a Function returns. Canonical reference: https://www.nyckel.com/docs/api/schemas/function-output-modality/ ### FunctionSummary Canonical reference: https://www.nyckel.com/docs/api/schemas/function-summary/ ### IFunctionInput Polymorphic base for all Function inputs (text, image, tabular row, …). Carriers a `size` field for bookkeeping. Canonical reference: https://www.nyckel.com/docs/api/schemas/i-function-input/ ### InvokeInput The request body for `InvokeFunction`. Canonical reference: https://www.nyckel.com/docs/api/schemas/invoke-input/ ### Label Ontology: Label One possible output of a Function. Carries an id, a human name, an optional description, and free-form `metadata`. Canonical reference: https://www.nyckel.com/docs/api/schemas/label/ ### LabelConfidence One Label / confidence / threshold triple inside a `FunctionOutput`. Canonical reference: https://www.nyckel.com/docs/api/schemas/label-confidence/ ### LabelCountDictionary A dictionary keyed by `labelId` whose values are integer counts. Canonical reference: https://www.nyckel.com/docs/api/schemas/label-count-dictionary/ ### Prediction Ontology: Prediction A single Label + confidence pair returned by a Function for a Sample. Canonical reference: https://www.nyckel.com/docs/api/schemas/prediction/ ### Sample Ontology: Sample One input recorded against a Function. May carry an `Annotation` (ground truth) and a `Prediction` (the model's guess). Canonical reference: https://www.nyckel.com/docs/api/schemas/sample/ ### SampleOrigin How a Sample entered the Function (manual upload vs `InvokeCapture`). Canonical reference: https://www.nyckel.com/docs/api/schemas/sample-origin/ ### SampleSetRelationship Membership of a Sample in a Sample Set, with an optional weight. Canonical reference: https://www.nyckel.com/docs/api/schemas/sample-set-relationship/ ### SampleSortBy Sort key for `ListSamples`. Canonical reference: https://www.nyckel.com/docs/api/schemas/sample-sort-by/ ### SearchInvokeInput The request body for invoking a Search Function. Canonical reference: https://www.nyckel.com/docs/api/schemas/search-invoke-input/ ### SearchSample One result returned by a Search Function — a Sample plus its `distance` from the query. Canonical reference: https://www.nyckel.com/docs/api/schemas/search-sample/ ### SortOrder Ascending or descending. Canonical reference: https://www.nyckel.com/docs/api/schemas/sort-order/ ### WritableField The mutable subset of `Field`. Canonical reference: https://www.nyckel.com/docs/api/schemas/writable-field/ ### WritableFunction The mutable subset of `Function` accepted on `POST`/`PUT`. Canonical reference: https://www.nyckel.com/docs/api/schemas/writable-function/ ### WritableLabel The mutable subset of `Label` accepted on `POST`/`PUT`. Canonical reference: https://www.nyckel.com/docs/api/schemas/writable-label/ ### WritableSample The mutable subset of `Sample` accepted on `POST`/`PUT`. Canonical reference: https://www.nyckel.com/docs/api/schemas/writable-sample/ ## Common questions Nyckel answers - How do I classify images with an API? - How do I classify text such as documents, emails, or support tickets? - How do I detect objects in images? - How do I build semantic search for documents or products? - How do I make predictions from structured or tabular data? - How do I combine images and metadata in a prediction model? - How do I start with zero-shot predictions and improve later? - How do I review and annotate real production samples? - How do I train a model using labeled examples? - How do I manage samples and annotations programmatically? - How do I add machine learning to my app without managing ML infrastructure? ## URLs - Homepage: https://www.nyckel.com/ - Documentation: https://www.nyckel.com/docs/ - API reference: https://www.nyckel.com/docs/api/ - OpenAPI spec: https://www.nyckel.com/openapi/v1.json - Full LLM doc: https://www.nyckel.com/llms-full.txt - Pretrained classifiers: https://www.nyckel.com/pretrained-classifiers/ - Pretrained detectors: https://www.nyckel.com/pretrained-detectors/