npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wiplist/embed

v3.2.3

Published

Embed Wiplist job and time creation into any website

Downloads

617

Readme

Wiplist Embed

A lightweight JavaScript SDK for embedding Wiplist job and time creation into any website.

Installation

CDN (script tag)

<script src="https://embed.wiplist.io/embed.js"></script>

npm

npm install @wiplist/embed

Quick start

Script tag

Add the script to your HTML, then initialise with your API key:

<script src="https://embed.wiplist.io/embed.js"></script>
<script>
  const wiplist = Wiplist({
    apiKey: "your_api_key",
    onJobCreated: function (job) {
      console.log("Created:", job.job_number, job.job_title);
    },
  });

  wiplist.createJob();
</script>

Download demo.html for a working script tag example you can open directly in your browser.

npm / ES module

import Wiplist from "@wiplist/embed";

const wiplist = Wiplist({ apiKey: "your_api_key" });
wiplist.createJob();

The API is identical regardless of how you load the SDK — only the installation method differs.

Get your API key from Wiplist under Settings → API Keys.

Configuration

const wiplist = Wiplist({
  // Required
  apiKey: "your_api_key",

  // Required: act as this user for created records.
  apiUser: "[email protected]",

  // Optional: modal height — any CSS value. Defaults to '70vh'.
  modalHeight: "600px",

  // Callbacks
  onJobCreated: function (job) {
    /* ... */
  },
  onTimeCreated: function (time) {
    /* ... */
  },
  onConnected: function () {
    /* ... */
  },
  onError: function (error) {
    /* ... */
  },
});

| Option | Type | Required | Description | | --------------- | -------- | -------- | ------------------------------------------------- | | apiKey | string | Yes | Your API key | | apiUser | string | Yes | Email of the user to act as for created records | | modalHeight | string | No | CSS height of the modal (default "70vh") | | onJobCreated | function | No | Called when a job is created | | onTimeCreated | function | No | Called when a time entry is created | | onConnected | function | No | Called when the widget authenticates successfully | | onError | function | No | Called on connection or auth failure |

Methods

wiplist.createJob(options?)

Opens the job creation form.

// Basic
wiplist.createJob();

// With pre-filled fields
wiplist.createJob({
  team_id: "xxxxx",
  user_id: "xxxxx",
  company_id: "xxxxx",
  contact_id: "xxxxx",
  workflow_id: "xxxxx",
  status: Wiplist.JobStatus.IN_PROGRESS,
  type: Wiplist.JobType.FIXED_PRICE,
  job_title: "Kitchen Renovation",
  description: "Full remodel",
  company_name: "Acme Corp",
});

| Option | Type | Description | | -------------- | ------ | ---------------------------------------- | | team_id | string | Associate with a team | | user_id | string | Assign to this user | | company_id | string | Associate with a company | | contact_id | string | Associate with a contact | | workflow_id | string | Use this workflow | | status | number | Initial status (see Wiplist.JobStatus) | | type | number | Job type (see Wiplist.JobType) | | job_title | string | Pre-fill the job title | | description | string | Pre-fill the description | | company_name | string | Pre-fill or look up a client by name |

wiplist.createTime(options?)

Opens the time entry form.

// Basic
wiplist.createTime();

// Pre-select a job
wiplist.createTime({ job_id: "xxxxx" });

| Option | Type | Description | | --------- | ------ | --------------------- | | job_id | string | Pre-select this job | | user_id | string | Log time as this user |

wiplist.close()

Programmatically closes the modal.

wiplist.destroy()

Removes the widget from the DOM and cleans up event listeners. Call this if you need to re-initialise with a different API key.

Status constants

Use Wiplist.JobStatus instead of raw integers for readability:

Wiplist.JobStatus.PENDING; // 200
Wiplist.JobStatus.IN_PROGRESS; // 210

Type constants

Use Wiplist.JobType instead of raw integers for readability:

Wiplist.JobType.NON_BILLABLE; // 10
Wiplist.JobType.FIXED_PRICE; // 20

Callback payloads

onJobCreated(job)

{
  id:           "xxxxx",           // hashid
  team_id:      "xxxxx",           // nullable
  user_id:      "xxxxx",           // nullable
  company_id:   "xxxxx",           // nullable
  workflow_id:  "xxxxx",           // nullable
  status:       200,
  type:         20,
  job_number:   "J-5432",
  job_title:    "Kitchen Renovation",
  description:  "Full remodel...",
  date_due:     "180000384",       // nullable
  created_at:   "180000384",
}

onTimeCreated(time)

{
  id:          "xxxxx",            // hashid
  job_id:      "xxxxx",
  description: "Cabinet work",     // nullable
  unit_price:  75.00,              // nullable
  time_total:  480,                // minutes
  date_start:  "180000384",
  date_end:    "180000384",
  created_at:  "180000384",
}

Troubleshooting

Widget fails to load

Check the browser console. The most common cause is a Content Security Policy blocking the iframe. Add embed.wiplist.io to your frame-src directive:

<meta
  http-equiv="Content-Security-Policy"
  content="frame-src https://embed.wiplist.io; script-src 'self' https://embed.wiplist.io;"
/>

"Connection failed" / onError fires

The API key is invalid or the widget couldn't reach the Wiplist API. Verify the key in your dashboard under Settings → Widget API Keys.

Modal opens but form is blank / users don't load

Your domain may not be listed as an allowed origin for the API key. Check the key settings in the dashboard.

Browser support

Chrome, Firefox, Safari, Edge — latest two versions. iOS Safari and Chrome for Android supported.

License

MIT