# IFC IDS Requirements Receipt (`l3digital/ifc-ids-receipt`) Actor

Experimental check of selected literal IDS 1.0 requirements using inline IFC4 STEP text and IDS XML. Get failed checks localized by STEP id, optional GlobalId, specification and requirement index. Finite profile only; no geometry or conformance certification.

- **URL**: https://apify.com/l3digital/ifc-ids-receipt.md
- **Developed by:** [L3Digital](https://apify.com/l3digital) (community)
- **Categories:** Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.05 / useful ifc ids requirements receipt

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## IFC IDS Requirements Receipt

Locate model elements that fail selected literal IDS1.0 requirements before
routing them to model review. Supply a small authorized IFC4 STEP model and its
IDS document; one bounded receipt localizes failed checks by
STEP id, optional GlobalId, class, specification and requirement index. It
reports exact applicability and conjunctive pass/fail counts without exposing
attribute or property values.

This experimental receipt does not inspect geometry, repair a model, infer
requirements or certify IFC/IDS, structural, regulatory or physical conformance.
Existing native/web/API validators are strong substitutes; customer demand and
savings from managed access remain unvalidated.

### Input

Run the always-uncharged bundled synthetic pair with:

```json
{"demo": true}
```

For real input, send one JSON object with `processingPermission: true`, nonempty
`ifcText` and `idsXml` strings. Both documents are inline; no paths, URLs,
archives, cloud credentials or other fetch instructions are accepted. `demo`
and `processingPermission` are actual booleans, default false. Demo requires
documents to be absent, even empty/null, and permission false or absent. Unknown
keys, NUL, malformed Unicode, coercion and mixed modes are refused before native work.

Only IFC4 STEP physical files with a normal header/end envelope are admitted.
IFC2X3, IFC4X3 and IFC XML are outside the profile. Native unsuccessful parser
status, exceptions or diagnostics yield a fixed uninspected refusal, without
native logs or exception text. This does not certify all IFC syntax: the native
parser can silently accept trailing text.

### Finite IDS profile

Use namespace `http://standards.buildingsmart.org/IDS`. The root contains optional
`info` followed by `specifications`, with 1–16 specifications. Each specification
has `ifcVersion="IFC4"`, a 1–128-character name, optional bounded identifier, one
exact entity applicability and supported literal requirements.

Exact classes are IFCWALL, IFCDOOR, IFCWINDOW, IFCSLAB, IFCBEAM and IFCCOLUMN.
Subtypes are not implicitly included. Applicability supports required
1/unbounded (default), optional 0/unbounded or prohibited 0/0. Prohibited
applicability has no requirements; other applicability has 1–16 conjunctive requirements.

Attribute requirements support only direct `Name`, `Description` and `Tag`,
with optional nonempty literal value and required/optional/prohibited cardinality
(default required). Property requirements support exact property-set/base-name
literals, mandatory IFCLABEL or IFCTEXT datatype, required cardinality only and
an optional nonempty literal value. Only single-value properties without unit
interpretation are admitted. Normal type inheritance and occurrence overrides
are resolved; duplicate/ambiguous sets or matching definitions and non-scalar
representations refuse processing rather than collapse into a pass.

Literal strings are case-sensitive. Required zero matches fail existence;
optional zero matches are explicitly not_applicable; prohibited zero matches
pass the selected absence check. Each element passes only if every declared
requirement passes. A failed selected requirement is a complete semantic result,
not a native runtime failure.

DTD/entities/external resources, regex/XSD restrictions, alternate namespaces,
classification/material/partOf, predefinedType, entity requirements and additional
applicability facets are refused. `schemaLocation` and allowed URI metadata are
inert; user XML never enters a native generic loader. Ordering, duplicate
singletons, attributes and literal shapes are checked. This is structural profile
admission, not full IDS document validation.

Pinned IfcTester0.9.0 mishandles optional direct attributes whose actual value is
None. This version uses the documented narrow compatibility rule: admitted
optional Name/Description/Tag with None passes; empty strings and present values
continue through native facets. Required and prohibited attributes are unchanged.
The receipt discloses this rule. Package versions and the native writer build
string are distinct provenance; an experimental native build label is not a maturity claim.

### Full report and failures

After successful delivery, the default dataset contains one full receipt object
and the default key-value store's `REPORT` JSON contains the identical object.
Use the Output tab's **Complete REPORT JSON** link or
`GET /v2/key-value-stores/{defaultKeyValueStoreId}/records/REPORT` with appropriate
Apify authorization. Dataset tables are summaries; retrieve the full JSON for
all specifications, elements and checks. Specification and requirement indexes
are zero-based; elements are ordered by ascending STEP id.

Statuses are `complete`, `refused` or `failed`. Outcomes are `review_findings`,
`no_findings_in_completed_checks` or `not_inspected`. No outcome means compliant,
valid, ready or safe. Refused/failed receipts use fixed sanitized reason codes.
Native crash, timeout or invalid/oversized output produces a fixed failed receipt
when the parent survives; platform termination may prevent any stored receipt.

### Recover and retain this run's evidence

1. Use your authorized Apify caller to [start asynchronously](https://docs.apify.com/api/v2/actors-runs-post). Save the returned run `id` and a caller-generated request key in your own records before proceeding; retain `defaultKeyValueStoreId` and `defaultDatasetId` from the run response.
2. Check `GET /v2/actor-runs/RUN_ID` with that saved ID ([run API](https://docs.apify.com/api/v2/actor-run-get)). If a wait or retrieval times out, check the same run again. A failed or timed-out run can still have stored output; inspect it before deciding what to do.
3. Retrieve the authoritative full receipt with `GET /v2/key-value-stores/STORE_ID/records/REPORT`, using that run's `defaultKeyValueStoreId` as `STORE_ID` ([record API](https://docs.apify.com/api/v2/key-value-store-record-get)). Its equal dataset item is available at `GET /v2/datasets/DATASET_ID/items?format=json`, using `defaultDatasetId` ([dataset items API](https://docs.apify.com/api/v2/dataset-items-get)). Check `REPORT` during failure recovery even if dataset delivery failed.
4. Export the full typed JSON, parse it and verify the input binding and decision-required evidence before acting or cleaning up. Keep `profile`, `catalogVersion` and `input.ifcSha256`/`input.idsSha256` with all specification, element and requirement results. `complete` can include failed selected requirements; it does not establish general IFC/IDS compliance.

Do not silently POST again after a failed retrieval. If the initial start response was lost and no run ID is known, reconcile your authorized run history against your recorded request and input before considering a paid restart. A missing response does not prove no run started; this workflow promises no universal start idempotency.

A table or optional dataset field projection can support a limited notification, but it is not the full report. Retain the run/storage IDs, the identity and version/profile fields above, and relevant coverage; retrieve omitted detail from this same run before making a detailed decision.

#### Selective cleanup

After the run is terminal, no restart is planned and your exported evidence has been parsed and verified, you may remove authorized copies you no longer need. Use your saved exact storage IDs, never a latest-run shortcut or an assumed shared store. See Apify's [record deletion](https://docs.apify.com/api/v2/key-value-store-record-delete) and [dataset deletion](https://docs.apify.com/api/v2/dataset-delete) references for platform operations, which were not exercised in this Actor's QA: deleting `INPUT` leaves `REPORT`; deleting `REPORT` does not delete the dataset. Input records, REPORT records, dataset items and external copies are separate. Removing one does not erase logs, exports, saved task input, source files or customer copies, or guarantee provider-wide erasure.

### Bounds and charging

| Bound | Maximum |
| --- | --- |
| IFC / IDS UTF-8 input | 1 MiB (1,048,576) / 64 KiB (65,536) bytes |
| Model instances / evaluations | 5,000 / 2,048 |
| Specifications / requirements each | 16 / 16 |
| XML depth / element count | 16 / 2,048 |
| Literal attribute value / property-set or property name | 256 / 128 characters |
| Serialized UTF-8 report | 1 MiB |
| Native child address space / CPU | 1 GiB / soft10, hard12 seconds |
| Child wall / adapter / candidate platform timeout | 15 / 55 / 60 seconds |
| Candidate platform memory | 512 MiB |

These are chosen design bounds, not measured scalability guarantees. A fresh
child installs Linux resource limits before native imports, uses an explicit
secret-free environment and one OpenBLAS/OMP thread, and suppresses native stdout,
stderr and tracebacks. The parent bounds pipes, kills/reaps at deadline and does
not retry. This is process/resource isolation, not a security sandbox.

The current price is **$0.05 per useful report**. Useful means non-demo and
complete with both documents
admitted and at least one specification fully evaluated. Selected requirement
failures and zero-match existence/absence/not-applicable results can be useful.
All demos, unsupported/invalid/over-limit and crash cases are uncharged. Equal
REPORT and dataset copies precede one eligible `report-produced` event. Storage,
deadline or charge failures fail the run without application replay; dataset
redirects are disabled and SDK charge idempotency remains in place.

Authorized input and output may persist in normal Apify storage. No automatic
deletion, original-input redaction, erasure or nonretention is promised. Reports
include bounded caller specification labels/identifiers and localization ids;
they omit source attribute/property values and arbitrary native reason strings.

IfcOpenShell and IfcTester are LGPL-3.0-or-later dependencies. See the
[official versioned source and license](https://github.com/IfcOpenShell/IfcOpenShell/tree/v0.9.0)
and the [LGPL terms](https://www.gnu.org/licenses/lgpl-3.0.html).
The image also retains `THIRD_PARTY_NOTICES.md` with dependency notices.

# Actor input Schema

## `demo` (type: `boolean`):

Fixed clean pair through the same isolated native path. Omit ifcText and idsXml entirely, including null/empty values, and leave permission false. Always uncharged.

## `processingPermission` (type: `boolean`):

Must be true for real input. Confirm authorization and accept ordinary Apify retention; false for demo.

## `ifcText` (type: `string`):

Nonempty IFC4 STEP physical file, at most1,048,576 UTF-8 bytes. No NUL, archive, IFC XML, path, URL, IFC2X3 or IFC4X3. Native diagnostics refuse inspection.

## `idsXml` (type: `string`):

Nonempty admitted literal profile, at most65,536 UTF-8 bytes. IDS namespace required; no DTD/entities/regex, classifications/materials/partOf or native generic XML loading. Exact six IFC4 classes and direct attributes/required typed text properties only.

## Actor input object example

```json
{
  "demo": true,
  "processingPermission": false
}
```

# Actor output Schema

## `dataset` (type: `string`):

One receipt object per run, including explicit coverage gaps.

## `report` (type: `string`):

The same object as the dataset receipt.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "demo": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("l3digital/ifc-ids-receipt").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "demo": True }

# Run the Actor and wait for it to finish
run = client.actor("l3digital/ifc-ids-receipt").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "demo": true
}' |
apify call l3digital/ifc-ids-receipt --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,l3digital/ifc-ids-receipt"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/c0s6xSrenwKcW5NUy/builds/mkViIwFvWx9khLGtp/openapi.json
