Join our Discord community — connect, share, and grow with us! Join Now

Workflows

Workflows enable users to build their own automations inside their workspaces.
"Workflows" consist of "Nodes," which can be seen as serverless functions that can be connected with each other.

Trigger

Manual (click button)

This is the default option. It means that the workflow only triggers when you manually click on "execute" in the workflow UI.

Cron (AWS cron)

Cron allows you to time your workflow execution very precisely (to the minute). We use the AWS Cron format to ensure a reliable scheduling experience.

Webhook (URL + payload)

OrbitType generates a webhook URL, which serves as your entry point. If a third-party app or your bot from a different client sends a POST request with a JSON body to this endpoint, it will serve as the input JSON for the first node. This input will also be saved in your workspace as an example to simplify testing. You can load it with "Load Input" in the first node’s code editor.

Database (table events and OrbitType API triggers)

As OrbitType is an integrated environment, you can listen for triggers from database tables. We support listening to creation, updates, and deletion events. The SQL request triggering the workflow must be executed using the OrbitType API and include a defined return value. For testing, the input is saved so it can be retrieved later.
If a row is updated, you will receive an array containing two objects as input—one with the old row and one with the new row. You can then use JavaScript within the node to precisely evaluate whether the changes should trigger the flow or whether to return early.

Versions/restore

Each workflow is version-controlled; with every save of a node, the complete workflow is saved. You can revert these versions using the Versions button, which then restores the version. It keeps 50 versions as backups.

Node types

Code Nodes

This is the default node. Inside this node, you can write code and set config values to use within the code.

Decorative Nodes

These are visual elements which help you document and visually organize the workflow plan. They can also provide useful context to Orbitype Intelligence.

Node settings

Entry Node

Each workflow has one specific entry node. It is the first one placed on the node canvas by convention or the one you set manually in the node settings.

Hard Limit

Nodes can run for up to 60 minutes. As you can chain nodes together, this can result in very long-running tasks. To prevent nodes from running too long in situations where they clearly should not exceed a few minutes, you can set a hard limit to cut off the runtime. This is not a graceful process, meaning you will receive no output if the node times out.
This can be very useful when experimenting with AI agents and prompts that are not optimized, which may lead to long-running tasks and wasted credits if no hard limit is set.

Naming

Proper naming of nodes helps you, your coworkers, and Orbitpye Intelligence better understand the purpose of each node. It is important to clearly name each node based on its function.

Node function structure + logging

Orbitype Nodes must use the following syntax, with only one function allowed. Inside this function, you can use normal Node.js. Please keep in mind that this is a serverless environment, so some OS-related functionality will not work.
In Orbitype functions, you never need to require or import anything. Instead, you can provide the allowed libraries and API products via dependency injection into the function and then use them.

async ({input}) => {
  return {output: input}
}


If you want to log information, it is recommended to create a debug array and push messages to it. At the end, you can return it alongside other things. This way, the next node can analyze errors or you can process them further.

Node Output / Next node param

Output einer Node

If you just return something in the function, this will be set as the output.
If you want to have more control and also use features like next, you need to return an object with the key output. Then you can put it in there, and it will become clean, not boxed input for the next node.

async () => {
  const output = Math.random() 
  return {output, 
next: output > 0.5 ? "idOfTheNextNode" : "idOfTheOtherNextNode"}
}

Next Attribute

The next attribute allows you to set the next node dynamically. This works only when two or more nodes are connected with the output handle of the node.

async () => {
  const output = Math.random() 
  return {output, next: output > 0.5 ? "idOfTheNextNode" : "idOfTheOtherNextNode"}
}

Flow types

Linear

This is an easy workflow, moving from a -> b -> c. It's the easiest and most common way.

Branching

If you have a workflow path which, at some point, needs to decide how to proceed with path a.a or path a.b, you can set the next parameter to test this.

Multi Input

Every workflow has only one entry node, but you can also add another node and connect it to the second node if this helps with testing an input payload. Later in the flow, it can also happen that you have multiple inputs. Keep in mind that the payload can vary in the input, as two or more different nodes may fill it. If you don't work with the same format in the previous nodes, then it can lead to errors in the node with the multiple inputs.

Looping

This is great to have conditions within a workflow, but keep in mind, wrong conditions can lead to endless loops, which can again burn tokens. Use looping only in very controlled settings with clear exit rules.

Sub Workflow Architecture

If a workflow consists of clearly separable sub-workflows, it mostly makes sense to build them into their own workflows and trigger them via webhooks. This way, you get a far more modular workspace structure and can use and test sub-parts in isolation.

Orbitype Environment Injections

Orbi Object

Workflow functions have access to an injected orbi object. It represents the current project context and lets you access project metadata, connectors, and configured credentials in a consistent way.

async ({ orbi }) => {
  const { id, name } = orbi.project
  return { projectId: id, projectName: name }
}

Connectors

orbi.project.connectors lists the connectors available in the current project (e.g. SQL, S3). Use this to discover what integrations exist and to reference connector IDs when needed.

async ({ orbi }) => {
  const connectors = orbi.project.connectors.map(c => ({
    id: c.id,
    name: c.name,
    implementation: c.implementation
  }))

  return { connectors }
}

Credentials

orbi.project.credentials contains configured credential entries for the current project. This is the recommended way to access credential values.

async ({ orbi, linkedin }) => {
  const accountId = orbi.project.credentials
    .find(x => x.name === 'linkedin')?.value

  if (!accountId) {
    throw new Error('Missing credential: linkedin')
  }

  const self = await linkedin.connect(accountId)
  return { providerId: self.provider_id }
}

API Keys

orbi.project.apiKeys contains API key metadata for the current project. Treat API keys as secrets: do not log them and do not return them in workflow output in production.

async ({ orbi }) => {
  const keys = orbi.project.apiKeys.map(k => ({
    name: k.name,
    connectorId: k.connectorId
  }))

  return { apiKeys: keys }
}

Deprecated: credentials Injection

The direct credentials injection is deprecated. Use orbi.project.credentials instead to keep workflows consistent and future-proof.

// deprecated
async ({ credentials }) => {
  const apiKey = credentials.myApiKey
  return { apiKey }
}

Note: Avoid returning secrets in outputs. Prefer using them only for authenticated calls inside the workflow.

Apollo Integration

Apollo Integration in Orbitype

This documentation describes all available Apollo actions in Orbitype.
It explains what each action does, which parameters are required, and provides one complete example that uses every Apollo action in a logical flow.

All Apollo functionality is available via the apollo object inside the Orbitype code environment.


Prerequisites

  • A credential with the name apollo exists in the project

  • The code runs inside an Orbitype function or agent

  • The Apollo account must be connected before any other action


Basic Usage Pattern

Every Apollo workflow follows this order:

  1. Connect the Apollo account

  2. Search people (raw or normalized)

  3. Enrich selected leads and track credits

Minimal setup:

async ({ orbi, apollo }) => {
  const credential = orbi.project.credentials.find(x => x.name === "apollo")
  if (!credential?.value) throw new Error("missing [apollo] credential")
  apollo.connect(credential.value)
}

Without connect(), all request methods fail.


Connection

apollo.connect(accessToken)

Description
Connects Apollo with a bearer access token.
This method must always be called first.

Parameters

  • accessToken (string, required)
    Apollo access token from credential value

Returns

{
  connected: true
}

Search

apollo.search(params)

Description
Raw people search through Apollo mixed_people API endpoint.

Parameters

  • params (object, optional)
    Raw Apollo query params (for example q_keywords, page, per_page)

Returns

  • object raw Apollo response (typically includes total_entries and people)


apollo.searchLeads(params)

Description
Normalized search result with stable lead fields.

Parameters

  • params (object, optional)
    Same query shape as search()

Returns

{
  totalEntries: number,
  leads: [
    {
      id: string,
      fullName: string,
      title: string,
      linkedinUrl: string,
      hasEmail: boolean,
      companyName: string
    }
  ]
}

Enrichment

apollo.enrichPerson(params)

Description
Raw enrichment call to Apollo people/match endpoint.

Parameters

  • params (object, optional)
    Apollo enrichment params (for example id, linkedin_url, reveal_personal_emails)

Returns

  • object raw enrichment response (typically includes person and request_id)


apollo.enrichById(personId, options)

Description
Enriches one person by Apollo person ID.

Parameters

  • personId (string, required)
    Apollo person ID

  • options (object, optional)
    Extra enrichment params merged into the request

Returns

{
  person: object | undefined,
  request_id: number | undefined
}

apollo.enrichByLinkedinUrl(linkedinUrl, options)

Description
Enriches one person by LinkedIn URL.

Parameters

  • linkedinUrl (string, required)
    Full LinkedIn URL

  • options (object, optional)
    Extra enrichment params merged into the request

Returns

{
  person: object | undefined,
  request_id: number | undefined
}

Combined Workflow Helper

apollo.searchAndEnrich(input)

Description
Searches leads by keywords and enriches a subset of results by ID.

Parameters

  • input (object, required)

    • query (string, required): keyword query

    • page (number, optional, default 1)

    • perPage (number, optional, default 10)

    • maxEnrich (number, optional, default 3, clamped to 0..25)

Returns

{
  search: {
    totalEntries: number,
    leads: ApolloLead[]
  },
  enriched: ApolloPerson[],
  errors: [
    {
      personId: string,
      message: string
    }
  ]
}

Credits

apollo.getCredits()

Description
Returns credit units consumed by this Apollo integration instance during execution.

Parameters

  • none

Returns

  • number


Complete Example Using All Apollo Actions

This example uses every available Apollo action exactly once in a realistic workflow.

async ({ orbi, apollo }) => {
  // 1) Connect Apollo account
  const credential = orbi.project.credentials.find(x => x.name === "apollo")
  if (!credential?.value) throw new Error("missing [apollo] credential")
  apollo.connect(credential.value)

  // 2) Raw search
  const rawSearch = await apollo.search({
    q_keywords: "founder saas zurich",
    page: 1,
    per_page: 5
  })

  // 3) Normalized search
  const normalized = await apollo.searchLeads({
    q_keywords: "founder saas zurich",
    page: 1,
    per_page: 5
  })

  // 4) Raw enrich (from raw search)
  const firstRawPerson = rawSearch?.people?.[0]
  let rawEnrichment = null
  if (firstRawPerson?.linkedin_url) {
    rawEnrichment = await apollo.enrichPerson({
      linkedin_url: firstRawPerson.linkedin_url,
      reveal_personal_emails: true
    })
  }

  // 5) Enrich by Apollo ID
  const firstLead = normalized.leads[0]
  let enrichById = null
  if (firstLead?.id) {
    enrichById = await apollo.enrichById(firstLead.id, {
      reveal_personal_emails: true
    })
  }

  // 6) Enrich by LinkedIn URL
  let enrichByLinkedin = null
  if (firstLead?.linkedinUrl) {
    enrichByLinkedin = await apollo.enrichByLinkedinUrl(firstLead.linkedinUrl, {
      reveal_personal_emails: true
    })
  }

  // 7) Combined helper
  const searchAndEnrich = await apollo.searchAndEnrich({
    query: "founder saas zurich",
    page: 1,
    perPage: 10,
    maxEnrich: 2
  })

  // 8) Credits
  const credits = apollo.getCredits()

  return {
    totals: {
      rawTotalEntries: rawSearch?.total_entries ?? 0,
      normalizedTotalEntries: normalized.totalEntries
    },
    firstLead,
    rawEnrichment,
    enrichById,
    enrichByLinkedin,
    searchAndEnrich,
    credits
  }
}

Agent

orbitype workflow functions have access to an injected agent object. it is a preconfigured wrapper around langchain with two methods: addTool() registers a tool run() runs the agent and returns the final message

example:

const func = async ({agent, zod}) => {
  const { z } = zod
  
  agent.addTool(
    (id) => {
      const url = `https://jsonplaceholder.typicode.com/todos/${id}`
      return fetch(url).then((x) => x.json())
    },
    {
      name: "fetch_todo",
      description: "Fetches a todo by ID from JSONPlaceholder",
      schema: z.string()
    },
  )
  
  agent.addTool(
    (text) => text.trim().split(/\s+/).length,
    {
      name: "count_words",
      description: "Counts the number of words in a given string",
      schema: z.string(),
      returnDirect: true,
    },
  )
  
  const data = await agent.run("number of words in todo with id 3")
  return data
}

SERP

orbitype workflow functions have access to an injected serp object. its search method performs a search engine query and returns an array of result URLs (ordered by relevance).

example:

async ({serp}) => {
  return {output: await serp.search('orbitype')}
}

output:

[
  "https://www.orbitype.com/",
  "https://uk.finance.yahoo.com/news/orbitype-com-launches-orbitype-intelligence-150000017.html",
  "https://www.orbitype.com/de",
  "https://app.orbitype.com/guest/register",
  "https://www.orbitype.com/posts",
  "https://www.globenewswire.com/news-release/2026/01/06/3213801/0/en/Orbitype-com-Launches-Orbitype-Intelligence-a-Chat-Based-Control-Layer-for-AI-Agent-Environments.html",
  "https://www.orbitype.com/vs",
  "https://www.crunchbase.com/organization/orbitype",
  "https://www.orbitype.com/vs/marketing-automation",
  "https://webcatalog.io/en/apps/orbitype"
]

Browser

orbitype workflow functions have access to an injected browser object. its run method executes puppeteer code remotely on a different server. the function passed as the first parameter is stringified and sent via http. the second parameter is json serialized and allows injecting variables from outside. finally, the result is returned.

example:

async ({browser}) => {
  const url = "https://vuejs.org/guide/introduction.html"
  const clicks = 3
  const html = await browser.run(
    // puppeteer code
    async ({page, data}) => {
      await page.goto(data.url)
      const button = page.locator(".demo > button")
      for (let i = 0; i < data.clicks; i++)
        await button.click()
      return button.map((x) => x.textContent).wait()
    },
    // injected variables
    {url, clicks}
  )
  return html
}

AI

Use AI Features easely in your nodes:

async ({ai}) => {
  const text = await ai.chat("This is a test")
  // -> "this is an answer..."
  const json = await ai.chat("JSON for red rgb color", true)
  // -> {r: 255, g: 0, b: 0}
  return {text , json}
}

async ({ai}) => {
  return await ai.image("a red apple")
  // -> { base64: "iVBORw..." }
}

async ({ai}) => {
  return await ai.embedding("lorem ipsum")
  // -> [-0.0014445713,-0.021729672, ... ]
}

OCR

orbitype workflow functions have access to an injected ocr object. fileToText() returns the plain text of a file. fileToTable() returns the tabular data extracted from file. fileToForm() returns fields from an PDF Formular

examples:

async ({ocr}) => {
  const url = "https://cdn.orbitype.com/sXbDwXihqsp0/pdfs/sample.pdf"
  const resp = await fetch(url)
  const blob = await resp.blob()
  const file = new File([blob], "dummmy.pdf", {type: "application/pdf"})
  const text = ocr.fileToText(file)
  return text
}

async ({ocr}) => {
  const url = "https://cdn.orbitype.com/sXbDwXihqsp0/pdfs/table.png"
  const resp = await fetch(url)
  const blob = await resp.blob()
  const file = new File([blob], "table.png", {type: "image/png"})
  const table = ocr.fileToTable(file)
  return table
}

async ({ocr}) => {
  const url = "https://cdn.orbitype.com/sXbDwXihqsp0/pdfs/table.png"
  const resp = await fetch(url)
  const blob = await resp.blob()
  const file = new File([blob], "table.png", {type: "image/png"})
  const table = ocr.fileToForm(file)
  return table
}

// tabular data is returned as a 2d array, e.g.
[
  ["name", "hex", "temperature"],
  ["red", "#FF0000", "warm"],
  ["blue", "#0000FF", "cold"],
  ["yellow", "#FFFF00", "warm"],
  ["cyan", "#00FFFF", "cold"]
]

LinkedIn (advanced)

LinkedIn Integration in Orbitype

This documentation describes all available LinkedIn actions in Orbitype.
It explains what each action does, which parameters are required, and provides one complete example that uses every LinkedIn action in a logical flow.

All LinkedIn functionality is available via the linkedin object inside the Orbitype code environment.


Prerequisites

  • A credential with the name linkedin exists in the project

  • The code runs inside an Orbitype function or agent

  • The LinkedIn account must be connected before any other action


Basic Usage Pattern

Every LinkedIn workflow follows this order:

  1. Connect the LinkedIn account

  2. Optionally fetch profiles or search results

  3. Perform actions like invitations, messages, or posts

Minimal setup:

async ({ orbi, linkedin }) => {
  const accountId = orbi.project.credentials.find(x => x.name === "linkedin").value
  await linkedin.connect(accountId)
}

Without connect(), no other method will work.


Connection

linkedin.connect(accountId)

Description
Connects the LinkedIn account and initializes the session.
This method must always be called first.

Parameters

  • accountId (string, required)
    Value from orbi.project.credentials for the credential named linkedin

Returns

{
  account_id: string,
  provider_id: string
}

provider_id represents your own LinkedIn profile and is required for posts and profile based queries.


Profiles and Search

linkedin.getProfile(identifier)

Description
Loads a LinkedIn profile using a profile identifier.

Parameters

  • identifier (string, required)
    LinkedIn profile handle from the URL, for example julian-vorraro

Returns (relevant fields)

{
  first_name: string,
  last_name: string,
  provider_id: string
}

linkedin.search(params)

Description
Searches for LinkedIn profiles using flexible search criteria.

Parameters

  • params (object, required)
    Search criteria, for example:

    • keywords (string)

Returns

  • Array<object> list of search result items


Invitations

linkedin.sendInvitation(providerId, message)

Description
Sends a connection request to a LinkedIn profile.

Parameters

  • providerId (string, required)
    Profile ID from getProfile() or search()

  • message (string, required)
    Invitation message text


linkedin.getInvitations()

Description
Returns all sent connection requests.

Parameters

  • none

Returns

  • object containing invitation items


linkedin.cancelInvitation(invitationId)

Description
Cancels a previously sent invitation.

Parameters

  • invitationId (string, required)
    Invitation ID from getInvitations()


Chats and Messages

linkedin.startChat(text, attendeesIds)

Description
Starts a new chat and sets it as the active chat.

Parameters

  • text (string, required)
    Initial message

  • attendeesIds (string[], optional)
    List of profile providerIds


linkedin.resumeChat(chatId)

Description
Sets an existing chat as the active chat.

Parameters

  • chatId (string, required)


linkedin.getChats()

Description
Lists existing chats.

Parameters

  • none


linkedin.getMessages()

Description
Fetches messages from the currently active chat.

Requirement

  • An active chat must be set


linkedin.sendMessage(text)

Description
Sends a message in the active chat.

Parameters

  • text (string, required)


Posts and Comments

linkedin.createPost(text)

Description
Creates a new LinkedIn post.

Parameters

  • text (string, required)


linkedin.getPosts(identifier)

Description
Fetches posts from a LinkedIn profile.

Parameters

  • identifier (string, required)
    Usually your own provider_id from connect()


linkedin.sendComment(postId, text)

Description
Adds a comment to a LinkedIn post.

Parameters

  • postId (string, required)
    Post ID from getPosts()

  • text (string, required)


Complete Example Using All LinkedIn Actions

This example uses every available LinkedIn action exactly once in a realistic workflow.

async ({ orbi, linkedin }) => {
  // 1) Connect LinkedIn account
  const accountId = orbi.project.credentials.find(x => x.name === "linkedin").value
  const self = await linkedin.connect(accountId)

  // 2) Search for people
  const searchResults = await linkedin.search({
    keywords: "Webentertainer GmbH"
  })

  // 3) Load a profile
  const profile = await linkedin.getProfile("julian-vorraro")

  // 4) Send invitation
  await linkedin.sendInvitation(
    profile.provider_id,
    "Hi Julian, quick connection?"
  )

  // 5) Fetch sent invitations
  const invitations = await linkedin.getInvitations()

  // 6) Cancel an invitation if needed
  if (invitations.items?.length) {
    await linkedin.cancelInvitation(invitations.items[0].invitation_id)
  }

  // 7) Start a chat
  await linkedin.startChat(
    "Thanks for connecting 👋",
    [profile.provider_id]
  )

  // 8) Send a message
  await linkedin.sendMessage("Quick exchange about automation?")

  // 9) Fetch chats
  const chats = await linkedin.getChats()

  // 10) Resume an existing chat
  if (chats.items?.length) {
    await linkedin.resumeChat(chats.items[0].id)
  }

  // 11) Fetch messages
  const messages = await linkedin.getMessages()
  console.log(messages.items?.map(m => m.text))

  // 12) Create a post
  await linkedin.createPost("Automation directly from Orbitype 🚀")

  // 13) Fetch own posts
  const posts = await linkedin.getPosts(self.provider_id)

  // 14) Comment on a post
  if (posts.items?.length) {
    await linkedin.sendComment(
      posts.items[0].id,
      "Thanks for reading"
    )
  }
}

Libraries

orbitype workflow functions have access to a few injected npm libraries.

  • cheerio

  • imapflow

  • lodash

  • nodemailer

  • pdf-lib (available as PDFLib)

  • pdfkit (available as PDFDocument)

  • unpdf

  • swissqrbill

  • zod

manually importing/requiring additional libraries is NOT SUPPORTED

examples:

const func = async ({lodash}) => {
  await new Promise((res) => setTimeout(res, 100))
  const output = lodash.random(0,9)
  return {output}
}

const func = async ({config, input, nodemailer}) => { 
  const transporter = nodemailer.createTransport({
    host: "smtp.ethereal.email",
    port: 587,
    auth: {
      user: config.user,
      pass: config.pass,
    },
  })
  const mail = {
    from: config.user,
    to: input.email,
    subject: config.subject,
    text: config.text,
  }
  await transporter.sendMail(mail)
  return mail
}

const func = async ({ImapFlow}) => {
  const client = new ImapFlow({
    host: 'smtp.ethereal.email',
    port: 993,
    secure: true,
    auth: {
      user: "nathanial.oreilly@ethereal.email",
      pass: "BnK2wAJtg4P1Efu5zp",
    }
  })
  await client.connect()
  await client.mailboxOpen('INBOX')
  const message = await client.fetchOne('*', { source: true })
  await client.logout()
  return message.source.toString()
}

const func = async ({unpdf}) => {
  const url = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
  const res = await fetch(url)
  const buffer = await res.arrayBuffer()
  const pdf = await unpdf.getDocumentProxy(new Uint8Array(buffer))
  const { text } = await unpdf.extractText(pdf, { mergePages: true })
  return text
}

const func = async ({PDFLib}) => {
  const pdfDoc = await PDFLib.PDFDocument.create()
  const page = pdfDoc.addPage()
  page.drawText('lorem ipsum')
  const base64 = await pdfDoc.saveAsBase64({ dataUri: true })
  return base64
}

const func = async ({SwissQRBill, PDFDocument}) => {
  return new Promise((resolve, reject) => {
    const doc = new PDFDocument({ size: 'A4' });
    const chunks = [];
    doc.on('data', (chunk) => chunks.push(chunk));
    doc.on('end', () => resolve(Buffer.concat(chunks).toString('base64')));
    doc.on('error', reject);

    doc.fontSize(20).text('Invoice #12345', 50, 50);
    doc.fontSize(12).text('Lorem ipsum...', 50, 100);

    const data = {
      amount: 1994.75,
      creditor: {
        account: "CH44 3199 9123 0008 8901 2",
        address: "Musterstrasse",
        buildingNumber: 7,
        city: "Musterstadt",
        country: "CH",
        name: "SwissQRBill",
        zip: 1234
      },
      currency: "CHF",
      debtor: {
        address: "Musterstrasse",
        buildingNumber: 1,
        city: "Musterstadt",
        country: "CH",
        name: "Peter Muster",
        zip: 1234
      },
      reference: "21 00000 00003 13947 14300 09017"
    };

    const qrBill = new SwissQRBill(data);
    qrBill.attachTo(doc);
    doc.end();
  });
}

SheetJS (XLSX): Spreadsheet processing

XLSX is SheetJS, a powerful spreadsheet processing library available in Orbitype workflows via dependency injection. It can read, create, edit, and export spreadsheets and tabular data across many formats, making it useful for imports, exports, reporting, and data transformation.

What SheetJS can do

  • Read spreadsheets and tabular data (for example: XLSX, XLS, CSV and more) from strings, ArrayBuffers, and other supported inputs.

  • Create and modify workbooks and worksheets programmatically.

  • Convert between formats (for example: CSV to XLSX, XLSX to CSV).

  • Transform data structures: sheet to JSON, JSON to sheet, arrays to sheet, and more.

  • Write/export files (for example: generate XLSX/CSV output for downloads, emails, or storage).

  • Work with cells: set values, number formats, dates, formulas, and basic worksheet metadata.

  • Utility helpers for handling ranges, headers, column mappings, and common spreadsheet operations.

example:

async ({ XLSX }) => {
  const csv = 
    `name, age, city, email
    John Doe, 30, New York, john@example.com
    Jane Smith, 25, Los Angeles, jane@example.com
    Bob Johnson, 35, Chicago, bob@example.com`;

  const workbook = XLSX.read(csv, { type: "string" });
  const sheet = workbook.Sheets['Sheet1'];
  const json = XLSX.utils.sheet_to_json(sheet);

  return json;
};

Notes:

  • The CSV header row becomes the object keys in the resulting JSON array.

  • XLSX.read parses the input into a workbook structure.

  • XLSX.utils.sheet_to_json converts worksheet rows into JSON objects.

Learn more

Cancel Account

To ensure you’re comfortable using Orbitype, we want to make sure everything is clear. If you have any questions or encounter issues understanding how something works, please don’t hesitate to reach out. We’re here to assist you—just send us a message at support@orbitype.com, and we’ll be happy to help you with any questions you have.