---
title: Native job defaults
description: Apply Loops variables and Iterable data/metadata defaults without changing the native service contract.
---

Loops and Iterable use native jobs rather than the common literal-message envelope. Their defaults live in separate entrypoints.

## Loops

```ts
import type { Layer } from "effect";
import { Effect } from "effect";
import { defaultedLoopsTransactionalLayer } from "@corven/email-sdk/loops-defaults";
import { LoopsTransactionalEmail } from "@corven/email-sdk/loops";

export const fictionalDefaultedLoopsSubmission = <E, R>(
  account: Layer.Layer<LoopsTransactionalEmail, E, R>,
) =>
  Effect.gen(function* sendDefaultedLoopsNotification() {
    const loops = yield* LoopsTransactionalEmail;

    return yield* loops.send(
      {
        dataVariables: { items: [{ amount: 0, title: "Fictional item" }] },
        email: "recipient@fictional.invalid",
        transactionalId: "host_selected_published_template",
      },
      { idempotencyKey: "caller-owned-logical-event" },
    );
  }).pipe(
    Effect.provide(
      defaultedLoopsTransactionalLayer(account, {
        dataVariables: { application: "Fictional application" },
        idempotencyKeyPrefix: "fictional-application/",
      }),
    ),
  );
```

`defaultedLoopsTransactionalLayer` supplies default `dataVariables` and an optional caller-key prefix. The application still selects the published template and recipient. It does not transform a native template into common `Email` content.

## Iterable

```ts
import { Effect, Redacted } from "effect";
import { defaultedIterableCampaignLayer } from "@corven/email-sdk/iterable-defaults";
import { IterableCampaignEmail, iterableCampaignLayer } from "@corven/email-sdk/iterable";

export const defaultedCampaignLayer = defaultedIterableCampaignLayer(
  iterableCampaignLayer({
    apiKey: Redacted.make("fictional-key"),
    campaignAuthority: "AuthorizeProviderManagedCampaign",
    contactWrites: "AuthorizeProfileCreation",
    dataRetention: "AuthorizePersistedSendData",
    projectIdentity: "EmailBased",
    region: "US",
    tracking: "AuthorizeCampaignTracking",
  }),
  { dataFields: { application: "fictional" }, metadata: { workflow: "fictional" } },
);

export const previewDefaultedCampaign = Effect.gen(function* previewDefaultedCampaign() {
  return yield* (yield* IterableCampaignEmail).validate({
    campaignId: 123,
    dataFields: { application: "operation override", enabled: false },
    recipientEmail: "recipient@fictional.invalid",
  });
});
```

`defaultedIterableCampaignLayer` merges default data fields and metadata. Caller values take precedence. The resulting job still passes native campaign validation, including project identity and scheduling constraints.

The examples leave HTTP transport to the application. Configuration attestations retain their original meaning after wrapping: defaults do not inspect remote templates, enable attachments, disable tracking or acquire profile-write permission.

See [Loops](/providers/loops) and [Iterable](/providers/iterable) for the native input and replay boundaries.
