diff --git a/packages/core/src/transports/offline.ts b/packages/core/src/transports/offline.ts
index 0b99baba1e4b..34f8c438529d 100644
--- a/packages/core/src/transports/offline.ts
+++ b/packages/core/src/transports/offline.ts
@@ -38,8 +38,19 @@ export interface OfflineTransportOptions extends InternalBaseTransportOptions {
    * @param envelope The envelope that failed to send.
    * @param error The error that occurred.
    * @param retryDelay The current retry delay in milliseconds.
+   * @returns Whether the envelope should be stored.
    */
   shouldStore?: (envelope: Envelope, error: Error, retryDelay: number) => boolean | Promise<boolean>;
+
+  /**
+   * Should an attempt be made to send the envelope to Sentry.
+   *
+   * If this function is supplied and returns false, `shouldStore` will be called to determine if the envelope should be stored.
+   *
+   * @param envelope The envelope that will be sent.
+   * @returns Whether we should attempt to send the envelope
+   */
+  shouldSend?: (envelope: Envelope) => boolean | Promise<boolean>;
 }
 
 type Timer = number | { unref?: () => void };
@@ -128,6 +139,10 @@ export function makeOfflineTransport<TO>(
       }
 
       try {
+        if (options.shouldSend && (await options.shouldSend(envelope)) === false) {
+          throw new Error('Envelope not sent because `shouldSend` callback returned false');
+        }
+
         const result = await transport.send(envelope);
 
         let delay = MIN_DELAY;
diff --git a/packages/core/test/lib/transports/offline.test.ts b/packages/core/test/lib/transports/offline.test.ts
index 0dfc550fcd38..cf3b414c0d0e 100644
--- a/packages/core/test/lib/transports/offline.test.ts
+++ b/packages/core/test/lib/transports/offline.test.ts
@@ -353,6 +353,27 @@ describe('makeOfflineTransport', () => {
     expect(getCalls()).toEqual([]);
   });
 
+  it('shouldSend can stop envelopes from being sent', async () => {
+    const { getCalls, store } = createTestStore();
+    const { getSendCount, baseTransport } = createTestTransport(new Error());
+    let queuedCount = 0;
+    const transport = makeOfflineTransport(baseTransport)({
+      ...transportOptions,
+      createStore: store,
+      shouldSend: () => false,
+      shouldStore: () => {
+        queuedCount += 1;
+        return true;
+      },
+    });
+    const result = transport.send(ERROR_ENVELOPE);
+
+    await expect(result).resolves.toEqual({});
+    expect(queuedCount).toEqual(1);
+    expect(getSendCount()).toEqual(0);
+    expect(getCalls()).toEqual(['push']);
+  });
+
   it('should not store client report envelopes on send failure', async () => {
     const { getCalls, store } = createTestStore();
     const { getSendCount, baseTransport } = createTestTransport(new Error());