> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Using Registration Parameters

> Use registration parameters in ABBYY Vantage to pass key-value metadata with API transactions for filtering, reporting, and custom processing.

export const VantageRegion = ({children}) => {
  const STORAGE_KEY = "abbyy.vantage.region";
  const REGIONS = [{
    code: "eu",
    label: "Europe"
  }, {
    code: "us",
    label: "North America"
  }, {
    code: "au",
    label: "Australia / Asia-Pacific"
  }];
  const [region, setRegion] = useState("eu");
  const [open, setOpen] = useState(false);
  const containerRef = useRef(null);
  const dropdownRef = useRef(null);
  function safeGetSavedRegion() {
    try {
      const saved = typeof window !== "undefined" ? window.localStorage.getItem(STORAGE_KEY) : null;
      const valid = new Set(REGIONS.map(r => r.code));
      return saved && valid.has(saved) ? saved : "eu";
    } catch {
      return "eu";
    }
  }
  function safeSetSavedRegion(code) {
    try {
      if (typeof window !== "undefined") {
        window.localStorage.setItem(STORAGE_KEY, code);
      }
    } catch {}
  }
  function dispatchRegionChanged(code) {
    try {
      if (typeof window !== "undefined") {
        window.dispatchEvent(new CustomEvent("abbyy:region-changed", {
          detail: {
            code
          }
        }));
      }
    } catch {}
  }
  function replaceRegionInString(text, currentRegion) {
    if (typeof text !== "string") return text;
    const hostRegex = /https:\/\/vantage-(eu|us|au)\.abbyy\.com/gi;
    const tokenRegex = /https:\/\/vantage-\[region\]\.abbyy\.com/gi;
    return text.replace(hostRegex, `https://vantage-${currentRegion}.abbyy.com`).replace(tokenRegex, `https://vantage-${currentRegion}.abbyy.com`);
  }
  useEffect(() => {
    setRegion(safeGetSavedRegion());
  }, []);
  useEffect(() => {
    const root = containerRef.current;
    if (!root) return;
    const anchors = root.querySelectorAll("a[href]");
    anchors.forEach(a => {
      const href = a.getAttribute("href");
      if (href) {
        const next = replaceRegionInString(href, region);
        if (next !== href) {
          a.setAttribute("href", next);
        }
      }
    });
    const walker = typeof document !== "undefined" ? document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null) : null;
    if (walker) {
      const toUpdate = [];
      let node = walker.nextNode();
      while (node) {
        const updated = replaceRegionInString(node.nodeValue, region);
        if (updated !== node.nodeValue) {
          toUpdate.push([node, updated]);
        }
        node = walker.nextNode();
      }
      toUpdate.forEach(([textNode, value]) => {
        textNode.nodeValue = value;
      });
    }
  }, [region, children]);
  useEffect(() => {
    const root = containerRef.current;
    if (!root) return;
    const anchors = root.querySelectorAll("a[href]");
    anchors.forEach(a => {
      a.style.fontWeight = "600";
      a.style.textDecoration = "underline";
      a.style.textUnderlineOffset = "2px";
    });
  }, [region, children]);
  useEffect(() => {
    const onRegionChanged = evt => {
      const code = evt && evt.detail && evt.detail.code;
      if (!code || code === region) return;
      setRegion(code);
    };
    if (typeof window !== "undefined") {
      window.addEventListener("abbyy:region-changed", onRegionChanged);
    }
    return () => {
      if (typeof window !== "undefined") {
        window.removeEventListener("abbyy:region-changed", onRegionChanged);
      }
    };
  }, [region]);
  useEffect(() => {
    const onClickAway = e => {
      if (!dropdownRef.current) return;
      if (!dropdownRef.current.contains(e.target)) {
        setOpen(false);
      }
    };
    document.addEventListener("click", onClickAway, true);
    return () => document.removeEventListener("click", onClickAway, true);
  }, []);
  const onSelect = code => {
    setRegion(code);
    safeSetSavedRegion(code);
    dispatchRegionChanged(code);
    setOpen(false);
  };
  const current = REGIONS.find(r => r.code === region) || REGIONS[0];
  return <div className="not-prose">
      <div className="mb-4 inline-flex items-center gap-2" ref={dropdownRef}>
        <span className="text-sm text-zinc-950/80 dark:text-white/80">Tenant Region:</span>
        <div className="relative">
          <button type="button" aria-haspopup="listbox" aria-expanded={open ? "true" : "false"} onClick={() => setOpen(v => !v)} className="h-8 px-3 rounded-md bg-zinc-900/5 dark:bg-white/5 border border-zinc-950/20 dark:border-white/20 text-sm inline-flex items-center gap-2">
            <span className="text-zinc-950 dark:text-white">{current.label}</span>
            <svg width="8" height="24" viewBox="0 -9 3 24" className="transition-transform text-gray-400 overflow-visible dark:text-gray-600 ml-auto" style={{
    transform: open ? "rotate(270deg)" : "rotate(90deg)"
  }}>
              <path d="M0 0L3 3L0 6" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"></path>
            </svg>
          </button>
          {open ? <div role="listbox" className="absolute z-50 left-full top-0 ml-2 w-56 rounded-xl border border-zinc-950/20 dark:border-white/20 bg-white dark:bg-zinc-900 shadow-lg p-2">
              {REGIONS.map(r => {
    const selected = r.code === region;
    return <button key={r.code} type="button" role="option" aria-selected={selected ? "true" : "false"} onClick={() => onSelect(r.code)} className={"w-full flex items-center justify-between px-3 py-2 rounded-lg text-sm hover:bg-zinc-950/5 dark:hover:bg-white/10 text-zinc-950 dark:text-white" + (selected ? " font-medium" : "")}>
                    <span style={selected ? {
      color: "#ff2038"
    } : undefined}>{r.label}</span>
                    <span className={selected ? "ml-3" : "ml-3 invisible"} style={selected ? {
      color: "#ff2038"
    } : undefined}>✓</span>
                  </button>;
  })}
            </div> : null}
        </div>
      </div>
      <div ref={containerRef} className="prose dark:prose-invert max-w-none">{children}</div>
    </div>;
};

## Using Registration Parameters

Transaction and file registration parameters are parameters consisting of key-value string pairs designed to provide additional user information (for example, client name, document type, and file source information). They are passed for processing along the transaction or the transaction documents. These parameters are available to all workers and can be used in various production scenarios:

* A program that uses ABBYY Vantage signs every transaction using an end-client attribute for the purposes of compiling reports and creating custom processing procedures (e.g. filtering counterparty data catalogs by client).
* A Scanning Station client (or a different origin for transactions) can pass the registration parameters of a document batch (such as an external correlation ID).

Registration parameters can be set using the Vantage API:

1. When creating an empty transaction or when initializing a transaction using the `launch` method. To do so, send a POST request to the `transactions` resource like in the example below:

<VantageRegion>
  ```
  POST https://vantage-us.abbyy.com/api/publicapi/v1/transactions
  ```
</VantageRegion>

or

<VantageRegion>
  ```
  POST https://vantage-us.abbyy.com/api/publicapi/v1/transactions/launch?skillId=skill-id
  ```
</VantageRegion>

In the request body, specify the registration parameters and run the following command:

<VantageRegion>
  ```bash theme={null}
  curl -X POST "https://vantage-us.abbyy.com/api/publicapi/v1/transactions" \
  -H "Authorization: Bearer token" \
  -H "Content-Type: application/json" \
  -d "{
    \"skillId\": \"123\",
    \"registrationParameters\": [
      {
        \"key\": \"key1\",
        \"value\": \"value1\"
      }
    ]
  }"
  ```
</VantageRegion>

2. When uploading files to a transaction or a document. To do so, send a POST request to the `transactions/<transaction-id>/files` resource like in the example below:

<VantageRegion>
  ```
  POST https://vantage-us.abbyy.com/api/publicapi/v1/transactions/transaction-id/files/
  ```
</VantageRegion>

In the request body, specify the registration parameters and run the following command:

<VantageRegion>
  ```bash theme={null}
  curl -X POST "https://vantage-us.abbyy.com/api/publicapi/v1/transactions/transaction-id/files/" \
  -H "Authorization: Bearer token" \
  -F "Files=@Invoice07.jpg; type=image/jpeg" \
  -F 'Model={
    "files": [
      {
        "index": 0,
        "imageProcessingOptions": {
          "autoCrop": "Default",
          "autoOrientation": "Default"
        },
        "registrationParameters": [
          {
            "key": "key1",
            "value": "value1"
          }
        ]
      }
    ]
  }'
  ```
</VantageRegion>

<Warning>
  There can be a maximum of 10 key-value type parameters, with the key parameter containing up to 128 characters and the value parameter containing up to 256 characters. The values of these parameters cannot be changed once they have been set.
</Warning>

Registration parameter values can be read:

* in Custom activity scripts,
* in External Export scripts in Output activity,
* in business rules.

You can get registration parameter values using the Vantage API as follows:

1. By calling the `registrationParameters` method for the `transactions/<transaction-id>/registrationParameters` resource:

<VantageRegion>
  ```
  GET https://vantage-us.abbyy.com/api/publicapi/v1/transactions/transaction-id/registrationParameters/
  ```
</VantageRegion>

The response will look like the following:

```json theme={null}
[
  {
    "key": "key1",
    "value": "value1"
  }
]
```

2. By using a `download` method call for the `transactions/<transaction-id>/files/<file-id>/download` resource to get the values in JSON format alongside the file being uploaded:

<VantageRegion>
  ```
  GET https://vantage-us.abbyy.com/api/publicapi/v1/transactions/transaction-id/files/file-id/download
  ```
</VantageRegion>
